home *** CD-ROM | disk | FTP | other *** search
/ The CIA World Factbook 1992 / k3bimage.iso / sel / 02 / 0035 / jmodem_f.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-02  |  22.5 KB  |  510 lines

  1. /****************************************************************************/
  2. /*   FILE JMODEM_F.C                                                        */
  3. /*   Created 11-JAN-1990                    Richard B. Johnson              */
  4. /*                                          405 Broughton Drive             */
  5. /*                                          Beverly, Massachusetts 01925    */
  6. /*                                          BBS (508) 922-3166              */
  7. /*                                                                          */
  8. /*   screen();         All screen output procedures. Uses INT 10H under     */
  9. /*                     MS-DOS.                                              */
  10. /*                                                                          */
  11. /*   These routines are absolutely not necessary and could be replaced      */
  12. /*   with _printf() statements. They are used to make the pretty screens    */
  13. /*   and overlapping windows that the PC community has grown to expect.     */
  14. /*   I didn't spend a lot of time on documentation.  _malloc() is used      */
  15. /*   to obtain memory for saving the screen-content. A failure to obtain    */
  16. /*   sufficient memory will not abort the program, just mess up the screen. */
  17. /*                                                                          */
  18. /****************************************************************************/
  19.  
  20. #include <stdio.h>
  21. #include <dos.h> 
  22. #include <stdlib.h>
  23. #include <malloc.h>
  24. #include <string.h>
  25. #include "screen.h"
  26. #include "jmodem.h"
  27.  
  28. short sav_par[boxes * param];                     /* Save row/columns       */
  29. short *buffer[boxes];                             /* Pointers for  boxes    */
  30. short last_box;                                   /* Last box on the screen */
  31. short start_txt;                                  /* Text starts in box     */
  32. short start_row;                                  /* Starting row of box    */
  33. short start_col;                                  /* Starting column of box */
  34. short end_row;                                    /* Ending row of box      */
  35. short end_col;                                    /* Ending column of box   */
  36. char  *signon[] = {
  37.                  "     J M O D E M",
  38.                  "File transfer protocol",
  39.                  "     "VERS
  40.                  };
  41.  
  42. char *sta_blk[] = {
  43.                   "   Block :" ,
  44.                   "  Length :" ,
  45.                   "   Bytes :" ,
  46.                   "Rate CPS :" ,
  47.                   "  Status :" ,
  48.                   "Synchronizing ...", 
  49.                   "  Receiving file ",
  50.                   "Transmitting file"
  51.                   };
  52.  
  53. char *fil_blk[] = {
  54.                   "Opening file ",
  55.                   "Can't open the file!",
  56.                   "Open okay",
  57.                   "File exists, renaming to ",
  58.                   "Can't create the file!",
  59.                   };
  60.  
  61. /****************************************************************************/
  62. /*                                C O D E                                   */
  63. /****************************************************************************/
  64. short screen (function,sys, text )
  65. short function;
  66. SYS  *sys;
  67. char *text;
  68. {
  69.     char string[80];                              /* Messages in windows    */
  70.     union REGS bios;                              /* For int 10H            */
  71.     register const ATTRIB *attr;                  /* For attribute table    */
  72.     register const short *index;                  /* Array pointer          */
  73.     unsigned screen;                              /* Screen attribute       */
  74.     short page;                                   /* Box number             */
  75.     short i;
  76.  
  77.     bios.x.ax =                                   /* Initialize             */
  78.     bios.x.bx =
  79.     bios.x.cx =
  80.     bios.x.dx = 0;
  81.  
  82.     switch (function)
  83.     {
  84.         case SCR_SGN:                             /* Sign-on message        */
  85.         {
  86.             page=0;                               /* Box number             */
  87.             kill_curs(&bios);
  88.             attr      = attribute + page;
  89.         screen    = attr->win;
  90.             index     = box_loc + (page * boxes);
  91.             start_row = *index++;
  92.             start_col = *index++;
  93.             end_row   = *index++;
  94.             end_col   = *index;
  95.             start_txt = start_row + 1;
  96.             set_box (page     ,                   /* Page                   */
  97.                      screen   ,                   /* Screen attribute       */
  98.                      start_row,                   /* Start row              */
  99.                      start_col,                   /* Start column           */
  100.                      end_row  ,                   /* End row                */
  101.                      end_col  ,                   /* End column             */
  102.                      sav_par  ,
  103.                      buffer   ,
  104.                      &bios  );
  105.             for (i = 0; i<3; i++)
  106.             {
  107.                 set_curs (start_txt++,start_col + 4,&bios);
  108.                 write_str(signon[i],attr->txt,&bios);
  109.             }
  110.             last_box = page;
  111.             break;
  112.         }
  113.     case SCR_FIL:                                 /* File screen            */
  114.         {
  115.             page=1;
  116.             attr      = attribute + page;
  117.             screen    = attr->win;
  118.         index     = box_loc + (page * boxes);
  119.         start_row = *index++;
  120.         start_col = *index++;
  121.         end_row   = *index++;
  122.         end_col   = *index;
  123.             start_txt = start_row + 1;
  124.             set_box (page     ,                   /* Page                   */
  125.                      screen   ,                   /* Screen attribute       */
  126.                      start_row,                   /* Start row              */
  127.                      start_col,                   /* Start column           */
  128.                      end_row  ,                   /* End row                */
  129.                      end_col  ,                   /* End column             */
  130.                      sav_par  ,
  131.                      buffer   ,
  132.                      &bios  );
  133.             set_curs (start_txt++,start_col + 4,&bios);
  134.             write_str(fil_blk[0],attr->txt,&bios);
  135.             write_str(text,attr->txt,&bios);
  136.             last_box=page;
  137.             break;
  138.         }
  139.     case SCR_FNF:                                 /* File not found         */
  140.         {
  141.             attr = attribute + last_box;
  142.             set_curs (start_txt++ ,start_col + 4, &bios);
  143.             write_str(fil_blk[1],attr->txt,&bios);
  144.             break;
  145.         }
  146.     case SCR_FOK:                                 /* File found okay        */
  147.         {
  148.             attr = attribute + last_box;
  149.             set_curs (start_txt++, start_col + 4, &bios);
  150.             write_str(fil_blk[2],attr->txt,&bios);
  151.             if (sys)
  152.             {
  153.                 strcpy(string,"File size = ");
  154.         ltoa (sys->s_byt,&string[12],10);
  155.                 set_curs (start_txt-1, start_col + 38, &bios);
  156.                 write_str(string,attr->txt,&bios);
  157.             }
  158.             break;
  159.         }
  160.     case SCR_STA:                                 /* Status block           */
  161.         {
  162.             page      = 2;
  163.             attr      = attribute + page;
  164.             screen    = attr->win;
  165.         index     = box_loc + (page * boxes);
  166.         start_row = *index++;
  167.         start_col = *index++;
  168.         end_row   = *index++;
  169.         end_col   = *index;
  170.             start_txt = start_row + 1;
  171.             set_box (page     ,                   /* Page                   */
  172.                      screen   ,                   /* Screen attribute       */
  173.                      start_row,                   /* Start row              */
  174.                      start_col,                   /* Start column           */
  175.                      end_row  ,                   /* End row                */
  176.                      end_col  ,                   /* End column             */
  177.                      sav_par  ,
  178.                      buffer   ,
  179.                      &bios  );
  180.  
  181.             for (i=0; i<6; i++)
  182.             {
  183.                 set_curs (start_txt+i,start_col + 4,&bios);
  184.                 write_str(sta_blk[i],attr->txt,&bios);
  185.             }
  186.             last_box = page;
  187.             break;
  188.         }
  189.    case SCR_FRN:                                  /* File renamed           */
  190.         {
  191.             attr = attribute + last_box;
  192.             set_curs (start_txt++, start_col + 4, &bios);
  193.             write_str(fil_blk[3],attr->txt,&bios);
  194.             write_str(text,attr->txt,&bios);
  195.             break;
  196.         }
  197.    case SCR_FCR:                                  /* File created           */
  198.         {
  199.             attr = attribute + last_box;
  200.             set_curs (start_txt++, start_col + 4, &bios);
  201.             write_str(fil_blk[4],attr->txt,&bios);
  202.             break;
  203.         }
  204.    case SCR_SYR:                                  /* Sync receive           */
  205.         {
  206.             attr = attribute + last_box;
  207.             start_txt = start_row + 1;
  208.             set_curs (start_txt + 5, start_col + 4, &bios);
  209.             write_str(sta_blk[6],attr->txt | 0x8000 ,&bios);
  210.             break;
  211.         }
  212.    case SCR_SYT:                                  /* Sync transmit          */
  213.         {
  214.             attr = attribute + last_box;
  215.             start_txt = start_row + 1;
  216.             set_curs (start_txt + 5, start_col + 4, &bios);
  217.             write_str(sta_blk[7],attr->txt | 0x8000,& bios);
  218.             break;
  219.         }
  220.     case SCR_SYS:
  221.         {
  222.         attr = attribute + last_box;
  223.         itoa(sys->s_blk,string,10);               /* Block number           */
  224.         set_curs (start_txt, start_col + 15, &bios);
  225.         write_str(string,attr->txt,& bios);
  226.  
  227.         memset(string,0x20,0x08);                 /* Fixed length string    */
  228.         string[0x07] = 0x00;                      /* Set a null             */
  229.         itoa(sys->s_len,string,10);               /* Block length           */
  230.     *(strchr(string,0x00)) = 0x20;            /* Fill in the NULL       */
  231.         set_curs (start_txt + 1, start_col + 15, &bios);
  232.         write_str(string,attr->txt,& bios);
  233.  
  234.         ltoa(sys->s_byt,string,10);               /* Total bytes            */
  235.         set_curs (start_txt + 2, start_col + 15, &bios);
  236.         write_str(string,attr->txt,& bios);
  237.  
  238.         memset(string,0x20,0x08);                 /* Fixed length string    */
  239.         string[0x07] = 0x00;                      /* Set a null             */
  240.         itoa(sys->s_cps,string,10);               /* Speed, cps             */
  241.     *(strchr(string,0x00)) = 0x20;            /* Fill in the NULL       */
  242.         set_curs (start_txt + 3, start_col + 15, &bios);
  243.         write_str(string,attr->txt,& bios);
  244.  
  245.         set_curs (start_txt + 4, start_col + 15, &bios);
  246.         write_str(sys->s_sta,attr->txt,& bios);
  247.         break;
  248.         }
  249.     case SCR_END:
  250.         {
  251.         for (page = last_box; page >=0; page--)
  252.             {
  253.             end_box (page,sav_par,buffer,&bios);
  254.             }
  255.         restore_curs(&bios);
  256.         break;
  257.         }
  258.     }
  259.     return 0;
  260. }
  261. /****************************************************************************/
  262. /*  Save screen contents in a buffer obtained from _malloc. Write a border  */
  263. /*  and screen attributes to saved screen location.  Record the address of  */
  264. /*  the buffer so the screen contents may be restored. Global *buffer[] is  */
  265. /*  used to save the pointers.                                              */
  266. /****************************************************************************/
  267. short set_box (page ,                             /* Box number             */
  268.              screen,                              /* Screen attribute       */
  269.              start_row,                           /* Start row of border    */
  270.              start_col,                           /* Start column of border */
  271.              end_row,                             /* End row of border      */
  272.              end_col,                             /* End column of border   */
  273.              sav_par,
  274.              buffer,
  275.              bios)
  276. short page;
  277. unsigned short screen;
  278. short start_row;
  279. short start_col;
  280. short end_row;
  281. short end_col;
  282. register short *sav_par;
  283. register short *buffer[];
  284. union REGS *bios;
  285. {
  286.     unsigned short putscr;
  287.     short sav_col;
  288.     short sav_row;
  289.     short row;
  290.     short col;
  291.     buffer[page] = (unsigned short *)
  292.                    allocate_memory (              /* Get pointer to memory  */
  293.                    ((end_row - start_row)
  294.                   * (end_col - start_col))
  295.                   *  sizeof (short) );
  296.     if (!buffer[page])
  297.         return(1);
  298.  
  299.     get_curs(bios);                               /* Get cursor position    */
  300.     sav_row    = (short) bios->h.dh;              /* Save cursor row        */
  301.     sav_col    = (short) bios->h.dl;              /* Save cursor column     */
  302.     sav_par   += (page * param);                  /* Calculate index once   */
  303.     *sav_par++ = (short) screen;
  304.     *sav_par++ = start_row;
  305.     *sav_par++ = start_col;
  306.     *sav_par++ = end_row;
  307.     *sav_par++ = end_col;
  308.     *sav_par++ = sav_row;
  309.     *sav_par   = sav_col;
  310.  
  311.    for (row = start_row; row < end_row; row++)
  312.         {
  313.         for (col = start_col; col < end_col; col++)
  314.             {
  315.             set_curs (row,col,bios);                   /* Set cursor pos    */
  316.             *buffer[page]++ = get_char_atr(bios);      /* Save char/attr    */
  317.             putscr = screen | 0x20;                    /* default (else)    */
  318.             if (row == start_row || row == end_row-1)  /* Top and bottom    */
  319.             putscr = screen | 205;
  320.             if (col == start_col || col == end_col-1)  /* Right and left    */
  321.             putscr = screen | 186;
  322.             if (row == start_row && col == start_col)  /* NW corner         */
  323.             putscr = screen | 201;
  324.             if (row == start_row && col == end_col-1)  /* NE corner         */
  325.             putscr = screen | 187;
  326.             if (row == end_row-1 && col == start_col)  /* SW corner         */
  327.             putscr = screen | 200;
  328.             if (row == end_row -1 && col == end_col-1) /* SE corner         */
  329.             putscr = screen | 188;
  330.             set_char_atr (putscr,bios);                /* Write to screen   */
  331.             }
  332.         }
  333.     return(0);
  334. }
  335. /****************************************************************************/
  336. /*  Restore the screen contents saved in memory pointed to by *buffer[].    */
  337. /****************************************************************************/
  338. short end_box (page,sav_par,buffer,bios)
  339. short page;
  340. register short *sav_par;
  341. register short *buffer[];
  342. union REGS *bios;
  343. {
  344.     unsigned screen;
  345.     short start_row;
  346.     short start_col;
  347.     short end_row;
  348.     short end_col;
  349.     short row;
  350.     short col;
  351.     short sav_row;
  352.     short sav_col;
  353.  
  354.     sav_par  += (page * param);                   /* Calculate index once   */
  355.     screen    = (unsigned) *sav_par++;            /* Restore from  array    */
  356.     start_row = *sav_par++;
  357.     start_col = *sav_par++;
  358.     end_row   = *sav_par++;
  359.     end_col   = *sav_par++;
  360.     sav_row   = *sav_par++;
  361.     sav_col   = *sav_par;
  362.  
  363.     buffer[page] -= ( (end_row - start_row)       /* Get buffer start       */
  364.                * (end_col - start_col) );
  365.  
  366.     for (row = start_row; row < end_row; row++)
  367.         {
  368.         for (col = start_col; col < end_col; col++)
  369.             {
  370.             set_curs (row,col,bios);              /* Set cursor pos         */
  371.             set_char_atr(*buffer[page]++,bios);   /* Restore screen         */
  372.             }
  373.         }
  374.     free(buffer[page]);                           /* Free alloc mem         */
  375.     set_curs (sav_row,sav_col,bios);              /* Restore cursor         */
  376.     return(0);
  377. }
  378. /****************************************************************************/
  379. /*                      Set Cursor to row, column                           */
  380. /****************************************************************************/
  381. void set_curs (row,col,bios)
  382. short row;
  383. short col;
  384. register union REGS *bios;
  385. {
  386.     bios->h.ah=(unsigned char) 0x02;              /* Set cursor function    */
  387.     bios->h.dh=(unsigned char)row;                /* Row                    */
  388.     bios->h.dl=(unsigned char)col;                /* Column                 */
  389.     bios->h.bh=(unsigned char) 0x00;              /* Page 0                 */
  390.     int86(VIDEO, bios, bios);                     /* Use for in and out     */
  391.     return;
  392. }
  393. /****************************************************************************/
  394. /*                          Get the cursor position                         */
  395. /****************************************************************************/
  396. void get_curs(bios)
  397. register union REGS *bios;
  398. {
  399.     bios->h.ah=(unsigned char) 0x03;              /* Get cursor function    */
  400.     bios->h.bh=(unsigned char) 0x00;              /* Page 0                 */
  401.     int86(VIDEO, bios, bios);                     /* Use for in and out     */
  402.     return;
  403. }
  404. /****************************************************************************/
  405. /*                           Turn off the cursor                            */
  406. /****************************************************************************/
  407. void kill_curs(bios)
  408. register union REGS *bios;
  409. {
  410.     bios->h.ah=(unsigned char) 0x01;              /* Set cursor function    */
  411.     bios->h.bh=(unsigned char) 0x00;              /* Page 0                 */
  412.     bios->x.cx=(unsigned short) 0xFFFF;           /* Kill the cursor        */
  413.     int86(VIDEO, bios, bios);                     /* Use for in and out     */
  414.     return;
  415. }
  416. /****************************************************************************/
  417. /*                         Restore the cursor type                          */
  418. /****************************************************************************/
  419. void restore_curs(bios)
  420. register union REGS *bios;
  421. {
  422.     bios->h.ah=(unsigned char) 0x01;              /* Get cursor function    */
  423.     bios->h.bh=(unsigned char) 0x00;              /* Page 0                 */
  424.     bios->x.cx=(unsigned short) 0x0607;           /* Restore the cursor     */
  425.     int86(VIDEO, bios, bios);                     /* Use for in and out     */
  426.     return;
  427. }
  428. /****************************************************************************/
  429. /*                    Write char /attr at cursor position                   */
  430. /****************************************************************************/
  431. void set_char_atr(atr_chr,bios)
  432. unsigned atr_chr;
  433. register union REGS *bios;
  434. {
  435.     bios->h.ah=(unsigned char) 0x09;              /* Write char function    */
  436.     bios->h.al=(unsigned char) (atr_chr & 0xFF);  /* Character              */
  437.     bios->x.cx=1;                                 /* One character          */
  438.     bios->h.bl=(unsigned char) (atr_chr >> 8);    /* Attribute              */
  439.     bios->h.bh=(unsigned char) 0x00;              /* Page 0                 */
  440.     int86(VIDEO, bios, bios);                     /* Use for in and out     */
  441.     return;
  442. }
  443. /****************************************************************************/
  444. /*                   Get char /attr at cursor position                      */
  445. /****************************************************************************/
  446. unsigned get_char_atr(bios)
  447. register union REGS *bios;
  448. {
  449.     bios->h.ah=(unsigned char) 0x08;              /* Read char function     */
  450.     bios->h.bh=(unsigned char) 0x00;              /* Page 0                 */
  451.     int86(VIDEO, bios, bios);                     /* Use for in and out     */
  452.     return (bios->x.ax);                          /* Its in the AX regis    */
  453.  }
  454. /****************************************************************************/
  455. /*         Write a string with attributes at current position               */
  456. /****************************************************************************/
  457. void write_str(string,atr,bios)
  458. register char *string;
  459. unsigned atr;
  460. register union REGS *bios;
  461. {
  462.     short row;
  463.     short col;
  464.     while (*string)                               /* Until the NULL         */
  465.     {
  466.     set_char_atr(atr|(short) *string++, bios);    /* Write char and attr    */
  467.     get_curs(bios);                               /* Get cursor position    */
  468.     row = (short) bios->h.dh;                     /* Get row                */
  469.     col = (short) bios->h.dl;                     /* Get column             */
  470.     set_curs (row,++col,bios);                    /* Set column             */
  471.     }
  472.     return;
  473. }
  474. /****************************************************************************/
  475. /*    Substitutes for the enormous _puts (char *) runtime module            */
  476. /*                                                                          */
  477. /*    The function has already been prototyped in STDIO.H as having an int  */
  478. /*    return type so I can't use the short (ANSI standard) return type in   */
  479. /*    the function itself.                                                  */
  480. /*                                                                          */
  481. /****************************************************************************/
  482.  
  483. int puts(string)
  484. register const char *string;
  485. {
  486.     union REGS bios;
  487.  
  488.     while (*string)
  489.     {
  490.         bios.h.al=(unsigned char) *string++;      /* Get character          */
  491.         bios.h.ah=(unsigned char) 0x0E;           /* Dumb terminal function */
  492.         bios.h.bh=(unsigned char) 0x00;           /* Page 0                 */
  493.         int86(VIDEO, &bios, &bios);               /* Use for in and out     */
  494.     }
  495.         bios.h.al=(unsigned char) 0x0D;           /* Carriage return        */
  496.         bios.h.ah=(unsigned char) 0x0E;           /* Dumb terminal function */
  497.         bios.h.bh=(unsigned char) 0x00;           /* Page 0                 */
  498.         int86(VIDEO, &bios, &bios);               /* Use for in and out     */
  499.  
  500.         bios.h.al=(unsigned char) 0x0A;           /* Linefeed               */
  501.         bios.h.ah=(unsigned char) 0x0E;           /* Dumb terminal function */
  502.         bios.h.bh=(unsigned char) 0x00;           /* Page 0                 */
  503.         int86(VIDEO, &bios, &bios);               /* Use for in and out     */
  504.  
  505.     return(0);
  506. }
  507. /****************************************************************************/
  508. /*                       E N D  O F  M O D U L E                            */
  509. /****************************************************************************/
  510.