{.PL65}
program sysmenu;

(* This program displays and executes a system menu via DOS batch file. *)
(* Program input is from sysmenu.txt which contains the menu items and  *)
(* lists of DOS commands. The program then copies the selected list of  *)
(* commands to a batch file - temp@@@@.bat - for subsequent execution.  *)
(* June 4, 1984  Joe Felton                                             *)

(*
Modification history:
   11/26/84     Fixed dropping characters after 1st up arrow key
*)

type
stdline    = string[80];
shline     = string[40];

const
cr         = 13;
uparrow    = 72;
dnarrow    = 80;
maxitem    = 20;

var
cmdfile,
batfile    : text;
dummy      : stdline;
menuitem   : array [0..maxitem] of stdline;
lineno     : array [0..maxitem] of integer;
selitem    : char;
err        : boolean;
indx,
itemcnt,
itemno,
lastitem,
arwkey,
ycoord,
topline,
linespc,
linecnt     : integer;

{.PA}
procedure dateid;
(* the purpose of this procedure is to imbed in the code the release date *)

     begin
          write ('11/28/84 pjf ver1.0');
     end;

procedure errcheck (var err : boolean; errmsg : shline);
(* this procedure checks ioresult for file error & prints error message *)

    begin
         err := (ioresult <> 0);
         if err then
                begin
                     writeln (errmsg);
                     write ('Press any key to continue..');
                     while not keypressed do;
                     read (kbd, selitem);
                end;
    end;


procedure writenorm (wline : stdline);
(* this procedure writes a line using normal video *)

    begin
         textbackground(0);
         textcolor(15);
         gotoxy (40-round((length(wline)+2)/2),ycoord);
         writeln (concat(' ',wline,' '));
         gotoxy (1,1);
    end; (* of procedure writenorm *)


procedure writerev (wline : stdline);
(* this procedure writes a line using reverse video *)

    begin
         textbackground(15);
         textcolor(0);
         gotoxy (40-round((length(wline)+2)/2),ycoord);
         writeln (concat(' ',wline,' '));
         gotoxy (1,1);
    end;  (* of procedure writerev *)


procedure getkey (var arrow : integer);
(* an inline code procedure to return the scan code of arrow keys. *)
(* the procedure will not return until an arrow key or <cr> is pressed. *)

    begin
      inline
        ($C4/$BE/ARROW/       {          LES   DI,ARROW[BP]   }
         $B4/$08/             { RKEY00:  MOV   AH,08          }
         $CD/$21/             {          INT   21H            }
         $3C/$0D/             {          CMP   AL,13          }
         $74/$18/             {          JZ    SHORT RKEY01   }
         $0C/$00/             {          OR    AL,00          }
         $75/$F4/             {          JNZ   SHORT RKEY00   }
         $B4/$08/             {          MOV   AH,08          }
         $CD/$21/             {          INT   21H            }
         $3C/$48/             {          CMP   AL,72          }
         $74/$0C/             {          JZ    SHORT RKEY01   }
         $3C/$4B/             {          CMP   AL,75          }
         $74/$08/             {          JZ    SHORT RKEY01   }
         $3C/$4D/             {          CMP   AL,77          }
         $74/$04/             {          JZ    SHORT RKEY01   }
         $3C/$50/             {          CMP   AL,80          }
         $75/$E4/             {          JNZ   SHORT RKEY00   }
         $88/$05);            { RKEY01:  MOV   ES:[DI],AL     }
     end;  (* of procedure getkey *)

{.PA}
begin  (* program sysmenu *)

assign (batfile, 'temp@@@@.bat');
assign (cmdfile, 'sysmenu.txt');
{$I-} rewrite (batfile); {$I+}
errcheck (err, 'Directory is full!');
if not err then
   begin
        {$I-} reset (cmdfile); {$I+}
        errcheck (err, 'File sysmenu.txt not found!');
   end;
if not err then
   begin

     readln (cmdfile, menuitem[0]);    (* READ THE MENU TITLE *)
     itemcnt := 0;
     textmode;
                                          (* READ ALL MENU ITEMS *)
     while ((menuitem[itemcnt] <> '') and (itemcnt <= maxitem)) do
           begin
                itemcnt := itemcnt +1;
                readln (cmdfile, menuitem[itemcnt]);
           end;
     itemcnt := itemcnt -1;     (* ADJUST COUNT FOR LAST '' READ *)
     if itemcnt < 11 then linespc := 2 else linespc := 1;
     topline := round((25 - (itemcnt * linespc +4))/2) +1;

     ycoord := topline;
     writenorm (menuitem[0]);   (* WRITE TITLE *)
     itemno := 1;
     for indx := 1 to itemcnt do   (* WRITE ALL MENU ITEMS *)
         begin
              ycoord := topline + (indx*linespc);
              lineno[indx] := ycoord;
              writenorm (menuitem[indx]);
         end;

     ycoord := topline+(indx*linespc) +2;
     writerev (concat('Use ',chr(24),chr(25),' to make your selection'));
     arwkey := 0;
     while arwkey <> uparrow do getkey (arwkey);
     writenorm ('  Press <return> to activate your selection');
     itemno := itemcnt +1;
     while arwkey <> cr do      (* DISPLAY SELECTION IN REVERSE VIDEO *)
           begin
                lastitem := itemno;
                if (arwkey = uparrow) and (itemno > 1)
                   then itemno := itemno -1;
                if (arwkey = dnarrow) and (itemno < itemcnt)
                   then itemno := itemno +1;
                if lastitem <> itemno then
                   begin
                        ycoord := lineno[lastitem];
                        if lastitem <> itemcnt+1 then     (* 11/26/84 fix *)
                           writenorm (menuitem[lastitem]);
                        ycoord := lineno[itemno];
                        writerev (menuitem[itemno]);
                     end;
                getkey (arwkey);
            end;

     indx := 1;
     while not eof (cmdfile) do    (* COPY DOS COMMANDS TO THE BATCH FILE *)
           begin
                readln (cmdfile, dummy);
                if indx = itemno then
                   writeln (batfile, dummy);
                if dummy = '' then indx := indx +1
            end;

     clrscr;

   end;  (* if no error opening one of the files *)

   close (batfile);
   close (cmdfile);

end.
(* end of program SYSMENU *)

 cls
        menu

        path \;\basic.sdr
        cd \games.sdr
        cls
        dir/w

        cd \dbase.sdr