home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / BDSC / BDSC-4 / CONFIG12.C < prev    next >
Text File  |  2000-06-30  |  24KB  |  905 lines

  1. /*  CONFIG.C -- Configuration Program for TVI 950
  2.       written in BDS C by Richard Conn
  3.  
  4. Program Name:  CONFIG.C
  5. Version:  1.2
  6. Date:  6 Oct 82
  7. Notes:
  8.  
  9.     The purpose of this program is to configure the TVI 950 CRT
  10.     to respond in a manner desired by the user.  Several of the
  11.     attributes of the TVI 950 are examined and set by this pgm.
  12.     These attributes include:
  13.  
  14.         . Function Key Definitions
  15.         . User Line Display
  16.         . Scrolling (Smooth or Hard)
  17.         . Tab Stops
  18.         . Video Display (Black on White or vice-versa)
  19.         . Key Click (On or Off)
  20.         . Cursor Type
  21.  
  22.     CONFIG runs in two basic modes -- Setup and Configure.
  23. Setup mode allows the user to set the various parameters of the
  24. terminal interactively.  Configure programs the terminal.  CONFIG
  25. is invoked by the following forms:
  26.  
  27.         CONFIG        <-- Programs the terminal from its internal
  28.                     configuration setting
  29.         CONFIG filename    <-- Programs the terminal from the settings
  30.                     given in the data file; if file
  31.                     type is not specified, a type of
  32.                     CFG is assumed; if the file is not
  33.                     found on the current drive, drive A:
  34.                     is examined (user areas not changed)
  35.         CONFIG /S    <-- Enter Setup mode; initial setting values
  36.                     are those already programmed into
  37.                     CONFIG
  38.         CONFIG fname /S    <-- Enter Setup mode with settings from the
  39.                     indicated file
  40.  
  41.     The data files created and read by this program and read by the
  42. accompanying TINIT program conform to the following structure:
  43.  
  44. Line 1:
  45.     Variable Values        Meaning
  46.     -------- ------        -------
  47.     cursor    '0' to '4'    Cursor Attributes
  48.     fkeys    'Y' or 'N'    Program Function Keys
  49.     click    '>' or '<'    Key Click On or Off
  50.     scroll    '8' or '9'    Enable Smooth or Hard Scrolling
  51.     tabs    'Y' or 'N'    Set Tab Stops
  52.     uline    'Y' or 'N'    Set and Display User Line
  53.     video    'b' or 'd'    Reverse or Normal Video
  54.  
  55.     These characters are followed by <CR> <LF>
  56.  
  57. Line n:
  58.     If uline=YES then text of ulbuffer (User Line); length is ullen;
  59.         text is followed by <CR> <LF>
  60.     If tabs=YES then text of tabbuffer (contains <SP> and '.'); length
  61.         is tablen; text is followed by <CR> <LF>
  62.     If fkeys=YES then text of fkeybuffer (22 strings of up to 20 chars
  63.         each); length is fkeylen; text is followed by <CR> <LF>
  64.  
  65. */
  66.  
  67. #define    version    12    /* Version Number */
  68.  
  69. /********************************************************************
  70.   Basic Definitions
  71.  ********************************************************************/
  72.  
  73. /*  Standard Header File  */
  74. #include    "A:BDSCIO.H"
  75.  
  76. /*  File Name and Mode Strings  */
  77. #define    configfile    "CONFIG.COM"        /* File Name */
  78. #define    configtype    ".CFG"            /* Data File Type */
  79. #define    configmode    0            /* Read/Only */
  80.  
  81. /*  Basic Constants  */
  82. #define    strlen    100    /* Max number of chars in a string */
  83. #define    ESC    0x1b    /* Escape code */
  84. #define    CR    '\r'    /* Carriage Return */
  85. #define    BEL    0x07    /* Ring Bell */
  86. #define    CTRLH    0x08    /* Backspace Char */
  87. #define    CTRLL    0x0c    /* Cursor Back */
  88. #define    CTRLU    0x15    /* Delete Line Char */
  89. #define    CTRLX    0x18    /* Delete Line Char */
  90. #define    RUBOUT    0x7f    /* Backspace Char */
  91.  
  92. #define    FALSE    0
  93. #define    TRUE    -1
  94. #define    echo    TRUE
  95. #define    noecho    FALSE
  96. #define    YES    'Y'
  97. #define    NO    'N'
  98.  
  99. /*  Buffer Sizes  */
  100. #define    ullen    81    /*  User Line Length of ULBUFFER  */
  101. #define    tablen    80    /*  Length of TABBUFFER  */
  102. #define    fkeylen    464    /*  Length of FKEYBUFFER  */
  103.  
  104. /*  Cursor Positioning  */
  105. #define    gotoxy    '='    /* Position Cursor */
  106.  
  107. /*  Clear Screen  */
  108. #define    clear    '+'    /* Clear screen */
  109.  
  110. /*  Function Keys  */
  111. #define    fctkey    '|'    /* Begin function key definition */
  112. #define    fctend    0x19    /* Ctrl-Y for end function key definition */
  113. #define    ctrlp    0x10    /* Control-P for char ESCAPE in Fct Key cmd */
  114.  
  115. /*  User Line  */
  116. #define    loadusr    'f'    /* Load User Line */
  117. #define    dispusr    'g'    /* Display User Line */
  118. #define    dispst    'h'    /* Display Status Line */
  119.  
  120. /*  Scrolling  */
  121. #define    sscroll    '8'    /* Enable Smooth Scrolling */
  122. #define    hscroll    '9'    /* Enable Hard Scrolling (no Smooth Scrolling) */
  123.  
  124. /*  Tabs  */
  125. #define    tabclr    '3'    /* Clear All Tabs */
  126. #define    tabset    '1'    /* Set Tab at Cursor */
  127.  
  128. /*  Video  */
  129. #define    vidnorm    'd'    /* Normal (white on black) Video */
  130. #define    vidrev    'b'    /* Reverse (black on white) Video */
  131.  
  132. /*  Key Click  */
  133. #define    clkon    '>'    /* Keyclick ON */
  134. #define    clkoff    '<'    /* Keyclick OFF */
  135.  
  136. /*  Cursor Type  */
  137. #define    curs    '.'    /* Set cursor attribute */
  138.  
  139. /********************************************************************
  140.   MAINLINE Routine
  141.  ********************************************************************/
  142.  
  143. char    cursor, click, scroll, uline, video, tabs, fkeys;
  144. char    ulbuffer[ullen], tabbuffer[tablen], fkeybuffer[fkeylen];
  145. char    iobuf[BUFSIZ];
  146.  
  147. main(argc,argv)
  148. int    argc;
  149. char    **argv;
  150. {
  151.     char *argstr;
  152.  
  153.     switch (argc) {
  154.        case 1  :    program(); break;
  155.        case 2  :    argstr = argv[1];  /* Pt to first arg */
  156.             if (*argstr == '/') {  /* SETUP or HELP */
  157.                 if (*++argstr == 'S') setup("");
  158.                 else help();  /* HELP if /non-S */
  159.                 }
  160.             else {
  161.                 readfile(argstr);
  162.                 program();
  163.                 }
  164.             break;
  165.        case 3  :    argstr = argv[2];  /* Pt to 2nd arg */
  166.             if ((*argstr == '/') && (*++argstr == 'S')) {
  167.                 readfile(argv[1]);
  168.                 setup(argv[1]);
  169.                 }
  170.             else help();
  171.             break;
  172.        default :    help(); break;
  173.        }
  174.     exit(TRUE);
  175. }  /* End of Mainline */
  176.  
  177. help()  /* HELP File */
  178. {
  179.     puts("\nCONFIG -- Configuration for TVI 950 Terminal");
  180.     puts("\n  CONFIG is invoked by one of the following forms --");
  181.     puts("\n\tCONFIG\t\t<-- Configured by internal settings");
  182.     puts("\n\tCONFIG /S\t\t<-- User Sets Up Configuration");
  183.     puts("\n\tCONFIG filename.typ\t<-- Configured by file");
  184.     puts("\n\tCONFIG filename.typ /S\t<-- Set Up from file");
  185. }
  186.  
  187. /********************************************************************
  188.   SETUP Routine to initialize a Configuration File
  189.  ********************************************************************/
  190.  
  191. setup(filename)  /* This is the master menu and command routine for setting up
  192.         the TVI 950 characteristics */
  193. char *filename;
  194. {
  195.     int  exit;
  196.     char ch;
  197.  
  198.     exit = FALSE;  /* Set no exit for now */
  199.     cmnd(hscroll);  /* Hard Scrolling for Displays */
  200.     cmnd(dispst);  /* Display Status Line */
  201.     newscreen (filename);  /* Display Banner and Menu */
  202.  
  203.     /* Main Command Processing Loop */
  204.     do {
  205.        at (14,17," "); at (14,17,""); ch = response(echo);
  206.        switch (ch) {
  207.         case CR  : newscreen(filename); break;
  208.         case 'C' : cursor=setcursor(); break;
  209.         case 'D' : status(); newscreen(filename); break;
  210.         case 'F' : fkeys=setfkeys(); newscreen(filename); break;
  211.         case 'K' : click=setclick(); break;
  212.         case 'P' : program(); newscreen(filename); break;
  213.         case 'S' : scroll=setscroll(); break;
  214.         case 'T' : tabs=settabs(); break;
  215.         case 'U' : uline=setuline(); break;
  216.         case 'V' : video=setvideo(); break;
  217.         case 'X' : exit = TRUE; break;
  218.         case 'Z' : readwrite(filename); break;
  219.         default  : cmderror(ch); break;
  220.         }
  221.     } while (!exit);
  222.  
  223.     cls();  /* Write exiting banner */
  224.     at (1,1,"CONFIG Exiting to CP/M");
  225. }
  226.  
  227. newscreen(filename)  /* Print menu of commands on screen */
  228. char *filename;
  229. {
  230.     int i;
  231.  
  232.     cls();  /* Clear Screen */
  233.     cmnd('$');  /* Graphics ON */
  234.     at (2,21,"bkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkc"); /* Title Box */
  235.     at (3,21,"j"); at (3,61,"j");
  236.     at (4,21,"akkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkd");
  237.     at (6,3,"bkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkc");  /* Left Box */
  238.     at (13,3,"akkkkkkkkkkkkkkkkkkkkkkkkkkkkkkd");
  239.     at (6,46,"bkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkc");  /* Right Box */
  240.     at (13,46,"akkkkkkkkkkkkkkkkkkkkkkkkkkkkkkd");
  241.     for (i=7;i<13;i++) {
  242.         at (i,3,"j"); at (i,34,"j");  /* Left Box */
  243.         at (i,46,"j"); at (i,77,"j");  /* Right Box */
  244.         }
  245.     for (i=3;i<79;i++) at (17,i,"k");  /* Dividing Line */
  246.     cmnd('%');  /* Graphics OFF */
  247.  
  248.     at (3,26,"");
  249.     printf("CONFIG for TVI 950, Version %d.%d",
  250.         version/10,version%10);  /* Title Box */
  251.  
  252.     at ( 7,5,"Commands to Set Attributes");  /* Left Box */
  253.     at ( 8,5,"Cmd Attribute   Cmd Attribute");
  254.     at ( 9,5," C  Cursor Type  S  Scrolling");
  255.     at (10,5," D  Disp Status  T  Tabs");
  256.     at (11,5," F  Fct Keys     U  User Line");
  257.     at (12,5," K  Key Click    V  Video");
  258.  
  259.     at ( 7,48,"Commands to Execute Functions");  /* Right Box */
  260.     at ( 8,48," Cmd Function");
  261.     at ( 9,48,"  P  Program TVI 950");
  262.     at (10,48,"  X  Exit to CP/M");
  263.     at (11,48,"  Z  Read/Write File");
  264.     at (12,48,"<cr> Refresh Screen");
  265.  
  266.     at (14,7,"Command?");  /* Command Line Prompt */
  267. }
  268.  
  269. setcursor()  /* Set cursor type */
  270. {
  271.     char ch;
  272.  
  273.     do {
  274.         clreos();  /* Clear Display Area */
  275.         at (18, 1,"Select Type of Cursor --");
  276.         at (19,10,"0 - No Cursor");
  277.         at (20,10,"1 - Blinking Block     2 - Steady Block");
  278.         at (21,10,"3 - Blinking Underline 4 - Steady Underline");
  279.         at (23,15,"Selection? "); ch=response(echo);
  280.     } while (('0' > ch) | (ch > '4'));
  281.     return(ch);
  282. }
  283.  
  284. status()  /* Display Status of CONFIG */
  285. {
  286.     char ch;
  287.     int i;
  288.  
  289.     cls();
  290.  
  291.     at (1,33,"CONFIG Status Display");
  292.  
  293.     cmnd('$');  /* Graphics ON */
  294.     at (1,32,"J"); at (1,54,"J");
  295.     at (2,32,"AKKKKKKKKKKKKKKKKKKKKKD");
  296.     cmnd('%');  /* Graphics OFF */
  297.  
  298.     if (fkeys == YES) fkeystatus();  /* Print Function Key Information */
  299.  
  300.     at (3,1,"User Line --");
  301.     if (uline == YES) printf("\n%s",ulbuffer);
  302.       else puts("\nUser Line is NOT DISPLAYED");
  303.  
  304.     at (5,1,"Tab Settings are --");
  305.     if (tabs == YES) {
  306.         printf("\n");
  307.         for (i=0; i<tablen; i++) putchar(tabbuffer[i]);
  308.         at (7,1,"");
  309.         for (i=1; i<=tablen; i++) if (i%5 == 0) {
  310.                 if (i == 5) printf("    5");
  311.                     else    printf("   %d",i);
  312.                 }
  313.         puts("\n");
  314.         }
  315.       else puts("\nTabs are NOT SET");
  316.  
  317.     at (11,1,"Key Click is ");
  318.     if (click == clkon) puts("ON"); else puts("OFF");
  319.  
  320.     at (12,1,"Cursor is ");
  321.     switch (cursor) {
  322.         case '0' : puts("NOT DISPLAYED"); break;
  323.         case '1' : puts("Blinking Block"); break;
  324.         case '2' : puts("Steady Block"); break;
  325.         case '3' : puts("Blinking Uline"); break;
  326.         default  : puts("Steady Uline"); break;
  327.         }
  328.  
  329.     at (13,1,"Scrolling is ");
  330.     if (scroll == sscroll) puts("Soft"); else puts("Hard");
  331.  
  332.     at (14,1,"Video is ");
  333.     if (video == vidnorm) puts("Normal"); else puts("Reverse");
  334.  
  335.     at (24,1,"Type Any Char to Cont -- "); ch=response(noecho);
  336. }
  337.  
  338. setfkeys()  /* This routine allows the user to define his function keys */
  339. {
  340.     char ch, *lptr, fstr[21], *tstr;
  341.     int fnum, *numptr, start, i;
  342.  
  343.     clreos();  /* Clear Display Area */
  344.     at (18,1,"Do you Wish to Initialize the Function Keys? ");
  345.     ch=response(noecho);
  346.     if (ch == YES) for (fnum=1;fnum<=22;fnum++) {  /* Init Keys */
  347.         lptr = fkeybuffer + (fnum-1)*20;
  348.         *lptr++ = '1';  /* Transmit to computer */
  349.         *lptr = '\0';  /* Init to empty */
  350.         }
  351.  
  352.     cls();  /* Clear Display Area */
  353.     at (1,34,"Function Key Programming");
  354.     cmnd('$');  /* Graphics ON */
  355.     at (1,33,"J"); at (1,58,"J");
  356.     at (2,33,"AKKKKKKKKKKKKKKKKKKKKKKKKD");
  357.     cmnd('%');  /* Graphics OFF */
  358.  
  359.     fkeystatus();  /* Print current settings of keys */
  360.  
  361.     /* Main Function Key Programming Command Loop */
  362.     do {
  363.         at (3,1,"Number of Function Key (0=Stop, 1-11=Fct)? ");
  364.         dots(2);
  365.         *numptr = 0; scanf("%d",numptr); fnum = *numptr;
  366.         if ((fnum < 1) | (fnum > 11)) fnum=0;
  367.  
  368.         if (fnum != 0) {
  369.             at (4,1,"Is this Key Shifted (Y/N)? ");
  370.             ch=response(echo);
  371.             if (ch == YES) fnum += 11;
  372.             at (5,1,"String for this Key? ");
  373.             dots(19); inline(fstr,19);
  374.             lptr = fkeybuffer + (fnum-1)*20;  /* Pt to key entry */
  375.             at (6,1,"Is this command locally executed? ");
  376.             ch=response(echo);
  377.             if (ch == YES) *lptr++ = '2';
  378.                 else *lptr++ = '1';
  379.             tstr = fstr;
  380.             while (*tstr != '\0') *lptr++ = *tstr++;
  381.             *lptr = '\0';
  382.             at (7,1,"Is this string to be ended by <RETURN>? ");
  383.             ch=response(echo);
  384.             if (ch == YES) {
  385.                 *lptr = '\r'; *++lptr = '\0';
  386.                 }
  387.             if (fnum > 11) {
  388.                 start = 53;  /* Set 2nd column */
  389.                 fnum -= 11;  /* Adjust to 1-11 */
  390.                 }
  391.                else start = 31;
  392.             for (i=start; i<start+20; i++) at (fnum+10, i, " ");
  393.             at (fnum+10,start,"");
  394.             prfkeystr(fstr);
  395.             }
  396.     } while (fnum != 0);
  397.     return(YES);
  398. }
  399.  
  400. fkeystatus()  /* Display Status of Function Keys */
  401. {
  402.     char ch;
  403.     int i;
  404.  
  405.     cmnd('$');  /* Graphics ON */
  406.     at (10,30,"B"); at (10,74,"C");  /* Draw Box for Fct Keys */
  407.     at (22,30,"A"); at (22,74,"D");
  408.     for (i=1; i<=11; i++) {
  409.         at (i+10,30,"J");
  410.         at (i+10,52,"J");
  411.         at (i+10,74,"J");
  412.         }
  413.     for (i=31; i<52; i++) {
  414.         at (10,i,"K");
  415.         at (22,i,"K");
  416.         }
  417.     at (10,52,"N"); at (22,52,"O");
  418.     for (i=53; i<=73; i++) {
  419.         at (10,i,"K");
  420.         at (22,i,"K");
  421.         }
  422.     cmnd('%');  /* Graphics OFF */
  423.  
  424.     /* Store current function key definitions in box */
  425.     for (i=1; i<=11; i++) {
  426.         at (i+10,31,"");
  427.         prfkeystr(fkeybuffer+(i-1)*20+1);
  428.         at (i+10,53,"");
  429.         prfkeystr(fkeybuffer+(i+10)*20+1);
  430.         }
  431.  
  432.     /* Box titles and numbers along left side of box */
  433.     at (9,31,"Function Key"); at (9,53,"Shifted Function Key");
  434.     for (i=1; i<=11; i++) {
  435.         if (i < 10) at (i+10,28,"");
  436.             else at (i+10,27,"");
  437.         printf("%d",i);
  438.         }
  439. }
  440.  
  441. setclick()  /* This routine turn the key click on or off */
  442. {
  443.     char ch;
  444.  
  445.     clreos();  /* Clear Display Area */
  446.     at (18, 1,"Do you want the Key Click ON? ");
  447.     ch=response(echo);
  448.     at (20,10,"Key Click is ");
  449.     if (ch==YES) {
  450.         puts("ON");
  451.         return(clkon);
  452.         }
  453.     else {
  454.         puts("OFF");
  455.         return(clkoff);
  456.         }
  457. }
  458.  
  459. setscroll()  /* This routine turn the smooth scroll on or off */
  460. {
  461.     char ch;
  462.  
  463.     clreos();  /* Clear Display Area */
  464.     at (18, 1,"Do you want Smooth Scrolling ON? ");
  465.     ch=response(echo);
  466.     at (20,10,"Smooth Scrolling is ");
  467.     if (ch==YES) {
  468.         puts("ON");
  469.         return(sscroll);
  470.         }
  471.     else {
  472.         puts("OFF");
  473.         return(hscroll);
  474.         }
  475. }
  476.  
  477. settabs()  /* This routine allows the user to specify tab locations */
  478. {
  479.     char *lptr, ch;
  480.     int i;
  481.  
  482.     clreos();  /* Clear Display Area */
  483.  
  484.     lptr = tabbuffer;  /* Pt to first char of tab buffer */
  485.     for (i=0;i<tablen;i++) *lptr++=' ';  /* Clear tab buffer */
  486.     i = 1; lptr = tabbuffer;  /* Set char pos and ptr to 1st char */
  487.  
  488.     at (18,1,"Do you wish to Enable Tabs? ");
  489.     ch=response(echo);
  490.     if (ch != YES) return(NO);
  491.  
  492.     at (18,1,"Set Tab Stops -- . Sets, <SPACE BAR> Clears");
  493.     at (19,1,"Left and Right Arrow Keys move Cursor Left and Right");
  494.     at (20,1,"<RETURN> terminates entry of tab stops");
  495.     at (24,1,"");
  496.     do {
  497.         ch=response(noecho);  /* Get char */
  498.         switch (ch) {
  499.             case CR :    break;
  500.             case ' ' :
  501.             case '.' :    *lptr++ = ch;  /* Store Char */
  502.                     putchar(ch);  /* Echo Char */
  503.                     i++;  /* Incr col counter */
  504.                     if (i > tablen) {  /* Beyond EOL */
  505.                         i--; lptr--;
  506.                         putchar(CTRLH);
  507.                         }
  508.                     break;
  509.             case CTRLH :    if (i == 1) putchar(BEL);
  510.                     else {  /* left arrow */
  511.                         i--; lptr--;
  512.                         putchar(ch);
  513.                         }
  514.                     break;
  515.             case CTRLL :    if (i == tablen) putchar(BEL);
  516.                     else {  /* right arrow */
  517.                         i++; lptr++;
  518.                         putchar(ch);
  519.                         }
  520.                     break;
  521.             default :    putchar(BEL); break;
  522.         }
  523.     } while (ch != CR);
  524.     return(YES);
  525. }
  526.  
  527. setuline()  /* This routine turn the smooth scroll on or off */
  528. {
  529.     char ch;
  530.  
  531.     clreos();  /* Clear Display Area */
  532.     at (18, 1,"Do you want the User Line Displayed? ");
  533.     ch=response(echo);
  534.     at (19,10,"User Line Display is ");
  535.     if (ch==YES) {
  536.         printf("ON\nOld User Line was --\n%s",ulbuffer);
  537.         printf("\nInput Your User Line --\n");
  538.         inline(ulbuffer,ullen);
  539.         return(YES);
  540.         }
  541.     else {
  542.         puts("OFF");
  543.         return(NO);
  544.         }
  545. }
  546.  
  547. setvideo()  /* This routine selects the screen video attribute */
  548. {
  549.     char ch;
  550.  
  551.     clreos();  /* Clear Display Area */
  552.     at (18, 1,"Do you want Reverse Video? ");
  553.     ch=response(echo);
  554.     if (ch==YES) {
  555.         at (20,10,"Reverse Video is ON");
  556.         return(vidrev);
  557.         }
  558.     else {
  559.         at (20,10,"Normal Video is ON");
  560.         return(vidnorm);
  561.         }
  562. }
  563.  
  564. readwrite(filename)  /* Read or Write a Data File or Write CONFIG.COM */
  565. char *filename;
  566. {
  567.    char ch, tname[20], oname[20], *bptr;
  568.    int fd, ioblen;
  569.  
  570.    oname[1] = '\0';  /* clear output file name */
  571.  
  572.    /* Loop until exit command specified */
  573.    do {
  574.     /* Input valid command */
  575.     do {
  576.         clreos();  /* Clear to end of screen */
  577.         at (18,1,"Select one of the following --");
  578.         at (19,1,"0 - Exit         1 - Read a File");
  579.         at (20,1,"2 - Write a File 3 - Write CONFIG.COM");
  580.         at (22,1,"Selection? "); ch=response(echo);
  581.     } while ((ch < '0') | (ch > '3'));
  582.     /* Get file name for Read or Write of a data file */
  583.     if ((ch == '1') | (ch == '2')) {
  584.         at (23,1,"Name of File (<RETURN> = ");
  585.         printf("%s)? ", filename);
  586.         dots(20); inline (tname,20);
  587.         bptr = tname;  /* Pt to first char of file name */
  588.         while (*bptr != '\0') {
  589.             *bptr = toupper(*bptr);
  590.             bptr++;
  591.             }
  592.         if (tname[0] == '\0') strcpy (oname,filename);
  593.             else strcpy (oname,tname);
  594.         }
  595.     switch (ch) {
  596.         case CR  : ch = '0'; break;  /* <CR> = Done */
  597.         case ' ' : ch = '0'; break;  /* <SP> = Done */
  598.         case '0' : break;
  599.         case '1' : readfile (oname); break;
  600.         case '2' : writefile (oname); break;
  601.         case '3' : printf("\nWriting CONFIG.COM to Disk");
  602.                 fd = fcreat(configfile, iobuf);
  603.                 ioblen = endext() - 0x100;
  604.                 bptr = 0x100;
  605.                 writebuffer (bptr, ioblen);
  606.                 fflush (iobuf);
  607.                 fclose (iobuf);
  608.                 break;
  609.         }
  610.    } while (ch != '0');
  611. }
  612.  
  613. cmderror(ch1)  /* Invalid Command Received -- Print error message */
  614. char ch1;
  615. {
  616.     clreos();  /* Clear to EOS from 18,1 */
  617.     at (18,1,"Invalid Command: ");
  618.     putchar(ch1);
  619. }
  620.  
  621. clreos()  /* Clear to End of Screen (EOS) for SETUP */
  622. {
  623.     at (18, 1,"");  /* Position Cursor */
  624.     printf("%c%c",ESC,'Y');
  625.     sleep(1);  /* Brief Delay */
  626. }
  627.  
  628. /********************************************************************
  629.   Routines to Read and Write Configuration Data
  630.  ********************************************************************/
  631.  
  632. readfile(name)  /* Read Indicated File */
  633. char *name;
  634. {
  635.     int fd, i, type;
  636.     char newfile[20], filename[20], *ptr;
  637.  
  638.     ptr = name;  /* Copy passed name into FILENAME */
  639.     type = FALSE;
  640.     i = 0;
  641.     while (*ptr != '\0') {
  642.         if (*ptr == '.') type = TRUE;  /* Note if file type given */
  643.         filename[i++] = *ptr++;
  644.         }
  645.     filename[i] = '\0';
  646.     if (!type) strcat (filename,configtype);  /* Set default file type */
  647.  
  648.     fd = fopen (filename, iobuf);  /* Try to open file */
  649.     if (fd == ERROR) {  /* If failure, try to open file on A: */
  650.         newfile[0] = '\0';
  651.         strcat (newfile,"A:");
  652.         strcat (newfile,filename);
  653.         fd = fopen (newfile, iobuf);
  654.         if (fd == ERROR) {  /* If this fails, give error */
  655.             printf("File %s not found", filename);
  656.             exit (FALSE);
  657.             }
  658.         }
  659.  
  660.     /* Read in parameters from disk file */
  661.     cursor = getc(iobuf);
  662.     if (('0'<=cursor) & (cursor<='4')) /* OK */;
  663.         else ferror();
  664.  
  665.     fkeys = getc(iobuf);
  666.     if ((fkeys == YES) | (fkeys == NO)) /* OK */;
  667.         else ferror();
  668.  
  669.     click = getc(iobuf);
  670.     if ((click == clkon) | (click == clkoff)) /* OK */;
  671.         else ferror();
  672.  
  673.     scroll = getc(iobuf);
  674.     if ((scroll == sscroll) | (scroll == hscroll)) /* OK */;
  675.         else ferror();
  676.  
  677.     tabs = getc(iobuf);
  678.     if ((tabs == YES) | (tabs == NO)) /* OK */;
  679.         else ferror();
  680.  
  681.     uline = getc(iobuf);
  682.     if ((uline == YES) | (uline == NO)) /* OK */;
  683.         else ferror();
  684.  
  685.     video = getc(iobuf);
  686.     if ((video == vidrev) | (video == vidnorm)) /* OK */;
  687.         else ferror();
  688.  
  689.     getc(iobuf); getc(iobuf);  /* Ignore <CR> <LF> */
  690.  
  691.     if (uline == YES) readbuffer (ulbuffer, ullen);
  692.  
  693.     if (tabs == YES) readbuffer (tabbuffer, tablen);
  694.  
  695.     if (fkeys == YES) readbuffer (fkeybuffer, fkeylen);
  696.  
  697.     fclose(iobuf);
  698. }
  699.  
  700. readbuffer (bufname, buflen)  /* Read into the buffer pted to by bufname */
  701. char *bufname;
  702. int buflen;
  703. {
  704.     int i, inch;
  705.     char *bptr;
  706.  
  707.     bptr = bufname;
  708.     for (i=1;i<=buflen;i++) {
  709.         inch = getc(iobuf);
  710.         if (inch == ERROR) ferror();
  711.         *bptr++ = inch;
  712.         }
  713.     getc(iobuf); getc(iobuf);  /* Flush <CR> <LF> */
  714. }
  715.  
  716. writefile (name)  /* Write the file to disk */
  717. char *name;
  718. {
  719.     int fd, i, type;
  720.     char filename[20], *ptr;
  721.  
  722.     ptr = name;  /* Copy passed name into FILENAME */
  723.     type = FALSE;
  724.     i = 0;
  725.     while (*ptr != '\0') {
  726.         if (*ptr == '.') type = TRUE;  /* Note if file type given */
  727.         filename[i++] = *ptr++;
  728.         }
  729.     filename[i] = '\0';
  730.     if (!type) strcat (filename,configtype);  /* Set default file type */
  731.  
  732.     fd = fcreat(filename, iobuf);  /* Create new file */
  733.     if (fd == ERROR) {
  734.         puts("\nDisk Full");
  735.         ferror();
  736.         }
  737.  
  738.     /* Write data into file */
  739.     putc (cursor, iobuf);
  740.     putc (fkeys, iobuf);
  741.     putc (click, iobuf);
  742.     putc (scroll, iobuf);
  743.     putc (tabs, iobuf);
  744.     putc (uline, iobuf);
  745.     putc (video, iobuf);
  746.     putc ('\r', iobuf);
  747.     putc ('\n', iobuf);
  748.     if (uline == YES) writebuffer (ulbuffer, ullen);
  749.     if (tabs == YES) writebuffer (tabbuffer, tablen);
  750.     if (fkeys == YES) writebuffer (fkeybuffer, fkeylen);
  751.  
  752.     /* Write out buffer and close file */
  753.     fflush(iobuf);
  754.     fclose(iobuf);
  755. }
  756.  
  757. writebuffer (bufname, buflen)  /* Write named buffer to disk */
  758. char *bufname;
  759. int buflen;
  760. {
  761.     int i;
  762.     char *bptr;
  763.  
  764.     bptr = bufname;
  765.     for (i=1;i<=buflen;i++) putc (*bptr++,iobuf);
  766.     putc ('\r',iobuf); putc ('\n',iobuf);
  767. }
  768.  
  769. program()  /* Program the Terminal */
  770. {
  771.     char *pstr;
  772.     int i;
  773.     char fch;
  774.  
  775.     printf("%c%c%c",ESC,curs,cursor);  /* Config Cursor Type */
  776.     if (fkeys == YES) {  /* Program Function Keys */
  777.         for (i=1;i<=22;i++) {
  778.             pstr = fkeybuffer + (i-1)*20;
  779.             fch = i+'1'-1;
  780.             if (*pstr != '\0')
  781.              printf("%c%c%c%s%c",ESC,fctkey,fch,pstr,fctend);
  782.             }
  783.         }
  784.     cmnd(click);  /* Set Key Click */
  785.     cmnd(scroll);  /* Set Scrolling */
  786.     if (tabs == YES) {  /* Set Tab Stops */
  787.         cmnd(tabclr);  /* Clear ALL Tab Stops */
  788.         printf("\n");
  789.         pstr = tabbuffer;
  790.         for (i=1;i<=80;i++) {
  791.             if (*pstr++ == '.') cmnd(tabset); 
  792.             putchar(' ');
  793.             }
  794.         printf("\n");
  795.         }
  796.     if (uline == YES) {  /* Program User Line */
  797.         printf("%c%c%s%c",ESC,loadusr,ulbuffer,'\r');
  798.         cmnd(dispusr);
  799.         }
  800.     cmnd(video);
  801.     cls();  /* New Screen */
  802. }
  803.  
  804. /********************************************************************
  805.   Primitive Functions
  806.  ********************************************************************/
  807.  
  808. prfkeystr(ptr)  /* Print function key string with <ESCAPE> char processing */
  809. char *ptr;
  810. {
  811.         while (*ptr != '\0') if (*ptr != ESC) putchar(*ptr++);
  812.             else {
  813.                 putchar('$');
  814.                 ptr++;
  815.                 }
  816. }
  817.  
  818. ferror() /* File Format Error Encountered */
  819. {
  820.     puts("\nAborting on Fatal Error in Data File");
  821.     exit (FALSE);
  822. }
  823.  
  824. dots(ndots)  /* Print Dots */
  825. int ndots;
  826. {
  827.     int i;
  828.     for (i=1;i<=ndots;i++) putchar('.');
  829.     for (i=1;i<=ndots;i++) putchar(CTRLH);
  830. }
  831.  
  832. inline(buffer,nchars)  /* Input a line from user into BUFFER */
  833. char *buffer;
  834. int nchars;
  835. {
  836.     int i, j;
  837.     char *lptr, ch;
  838.  
  839.     i = 1; lptr = buffer;  /* Init count and ptr */
  840.     do {
  841.         ch=bios(3);  /* Get char with no echo and no caps */
  842.         switch (ch) {
  843.             case CR :    *lptr = '\0';  /* End String */
  844.                     break;
  845.             case RUBOUT :
  846.             case CTRLH :    if (i == 1) putchar(BEL);
  847.                     else {
  848.                         i--; lptr--;
  849.                         rubout();
  850.                         }
  851.                     break;
  852.             case CTRLU :
  853.             case CTRLX :    for (j=i;j>1;j--) {
  854.                         rubout();
  855.                         }
  856.                     i = 1; lptr = buffer;
  857.                     break;
  858.             default :    if (i == nchars) putchar(BEL);
  859.                     else {
  860.                         *lptr++ = ch;
  861.                         i++;
  862.                         if (ch != ESC) putchar(ch);
  863.                             else putchar('$');
  864.                         }
  865.                     break;
  866.         }
  867.     } while (ch != CR);
  868. }
  869.  
  870. rubout()  /* Echo Backspace, Space, Backspace */
  871. {
  872.     putchar(CTRLH); putchar(' '); putchar(CTRLH);
  873. }
  874.  
  875. response(echo_on)  /* Get response from user */
  876. int echo_on;
  877. {
  878.     char ch;
  879.  
  880.     ch = bios(3);  /* Get character from user */
  881.     ch = toupper(ch);  /* Capitalize */
  882.     if (echo_on) bios(4,ch);
  883.     return (ch);
  884. }
  885.  
  886. cls()  /* Clear the Screen */
  887. {
  888.     cmnd(clear);
  889.     sleep(1);  /* Delay briefly for terminal */
  890. }
  891.  
  892. at(row,col,string)  /* Write <string> at <row,col> address on screen */
  893. int row, col;
  894. char *string;
  895. {
  896.     printf("%c%c%c%c%s",ESC,gotoxy,row+' '-1,col+' '-1,string);
  897. }
  898.  
  899. cmnd(ch1)  /* Issue <ESC><ch1> Command */
  900. char ch1;
  901. {
  902.     printf("%c%c",ESC,ch1);
  903. }
  904.  
  905.