home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / sampler / 01 / counter / counter2.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-09-09  |  19.2 KB  |  871 lines

  1. {
  2.                        F i l e    I n f o r m a t i o n
  3.  
  4. * DESCRIPTION
  5. Include source code file for COUNTER.PAS.
  6.  
  7. * ASSOCIATED FILES
  8. COUNTER.PAS
  9. COUNTER1.PAS
  10. COUNTER2.PAS
  11. COUNTER3.PAS
  12. COUNTER.EXE
  13.  
  14. }
  15.  
  16.  
  17. {------------------------------------------------ procedure EraseWarning }
  18.  
  19. {
  20. purpose: to erase all screen output to lines 18 to 23; that is where
  21.          all warnings are displayed.
  22. }
  23.  
  24. procedure EraseWarning;
  25.  
  26. var
  27.  i:byte;
  28.  
  29. begin {procedure EraseWarning}
  30.  
  31.  for i:=18 to 23 do
  32.  begin
  33.   gotoxy(1,i); clreol;
  34.  end; {for .. to loop}
  35.  
  36. end; {procedure EraseWarning}
  37.  
  38. {------------------------------------------------ proceudure SetTextType }
  39.  
  40. {
  41. purpose: to modify the text attributes of the output to the screen.
  42. }
  43.  
  44. procedure SetTextType(TextTypeVar:TextType);
  45.  
  46. begin {procedure SetTextType}
  47.  
  48.  case TextTypeVar of
  49.           Norm:begin
  50.                 TextColor(7);
  51.                 TextBackground(0);
  52.                end;
  53.        NormUnd:begin
  54.                 TextColor(1);
  55.                 TextBackground(0);
  56.                end;
  57.      NormBlink:begin
  58.                 TextColor(18);
  59.                 TextBackground(0);
  60.                end;
  61.   NormUndBlink:begin
  62.                 TextColor(17);
  63.                 TextBackground(0);
  64.                end;
  65.           High:begin
  66.                 TextColor(10);
  67.                 TextBackground(0);
  68.                end;
  69.        HighUnd:begin
  70.                 TextColor(9);
  71.                 TextBackground(0);
  72.                end;
  73.      HighBlink:begin
  74.                 TextColor(26);
  75.                 TextBackground(0);
  76.                end;
  77.   HighUndBlink:begin
  78.                 TextColor(25);
  79.                 TextBackground(0);
  80.                end;
  81.            Rev:begin
  82.                 TextColor(8);
  83.                 TextBackground(7);
  84.                end;
  85.       RevBlink:begin
  86.                 TextColor(16);
  87.                 TextBackground(7);
  88.                end;
  89.  end; {case TextTypeVar}
  90.  
  91. end; {procedure SetTextType}
  92.  
  93.  
  94. {-------------------------------------------------- procedure CEHandler }
  95. {$F+}
  96. procedure CEHandler (Flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP:word);
  97. Interrupt;
  98.  
  99. {
  100. purpose: to handle critical errors without allowing DOS to take over.
  101.          This procedure and its 3 related functions (below) are modified
  102.          from those developed by Kent Porter and published in the
  103.          February 1988 issue of Dr. Dobbs Journal of Software Tools.
  104. }
  105.  
  106. var
  107.  ah,al:byte;
  108.  ch:char;
  109.  
  110. {-------------------------------------------------- function GiveReason }
  111.  
  112. {
  113. purpose: to explain reason for critical error.
  114. }
  115.  
  116. function GiveReason (Error:byte):Str40;
  117.  
  118. begin {function GiveReason}
  119.  
  120.  case Error of
  121.    $00:GiveReason:=(' Write protect                          ');
  122.    $01:GiveReason:=(' Unknown unit                           ');
  123.    $02:GiveReason:=(' Drive not ready                        ');
  124.    $03:GiveReason:=(' Unknown command                        ');
  125.    $04:GiveReason:=(' CRC data error                         ');
  126.    $05:GiveReason:=(' Bad request structure length           ');
  127.    $06:GiveReason:=(' Seek error                             ');
  128.    $07:GiveReason:=(' Unknown media type                     ');
  129.    $08:GiveReason:=(' Sector not found                       ');
  130.    $0A:GiveReason:=(' Write fault                            ');
  131.    $0B:GiveReason:=(' Read fault                             ');
  132.    $0C:GiveReason:=(' General failure                        ');
  133.    $0D:GiveReason:=(' Bad file allocation table              ');
  134.    else GiveReason:=(' Unknown                                ');
  135.  end; {case Error}
  136.  
  137. end; {function GiveReason}
  138.  
  139. {-------------------------------------------------- function DiskError }
  140.  
  141. {
  142. purpose: to handle critical disk errors.
  143. }
  144.  
  145. function DiskError:word;
  146.  
  147. var
  148.  area,why:byte;
  149.  
  150. begin {function DiskError}
  151.  
  152.  S:='';
  153.  CriticalErrorDrive:=AL;
  154.  S:=' Disk error on drive '+char (AL+65);
  155.  while length(S)<40 do S:=S+' ';
  156.  gotoxy(1,19); write (S);
  157.  area:=(AH and 6) shr 1;
  158.  gotoxy(1,20);
  159.  case area of
  160.    0:write (' Error in DOS communications area       ');
  161.    2:write (' Error in disk directory                ');
  162.    3:write (' Error in files area                    ');
  163.  else write ('                                        ');
  164.  end; {case area}
  165.  why:=lo(DI);
  166.  SetTextType(RevBlink);
  167.  gotoxy(1,21); write (GiveReason(why));
  168.  SetTextType(Rev);
  169.  DiskError:=why;
  170.  
  171. end; {function DiskError}
  172.  
  173. {-------------------------------------------------- function NonDiskError }
  174.  
  175. {
  176. purpose: to handle critical non-disk errors.
  177. }
  178.  
  179. function NonDiskError:word;
  180.  
  181. var
  182.  why:byte;
  183.  DeviceAttr:^word;
  184.  DeviceName:^char;
  185.  ch:ShortInt;
  186.  
  187. begin {function NonDiskError}
  188.  
  189.  DeviceAttr:=ptr(BP,SI+4);
  190.  if (DeviceAttr^ and $8000) <> 0 then
  191.  begin
  192.   gotoxy(1,19); write (' Character device error                 ');
  193.   gotoxy(1,20); write (' Failing device is                      ');
  194.   S:='';
  195.   ch:=0;
  196.   repeat
  197.    DeviceName:=ptr(BP,SI+$0A+ch);
  198.    S:=S+(DeviceName^);
  199.    inc(ch);
  200.   until (DeviceName^=chr(0)) or (ch>7);
  201.   while length(S)<40 do S:=S+' ';
  202.   SetTextType(RevBlink);
  203.   gotoxy(1,21); write (S);
  204.   SetTextType(Rev);
  205.  end
  206.  else
  207.  begin
  208.   gotoxy(1,19); write (' Disk error has occurred                ');
  209.   gotoxy(1,20); write (' Probable cause:                        ');
  210.   why:=$0D;
  211.   SetTextType(RevBlink);
  212.   gotoxy(1,21); write (GiveReason(why));
  213.   SetTextType(Rev);
  214.  end; {if (DeviceAttr^ and $8000) <> 0}
  215.  NonDiskError:=why
  216.  
  217. end; {function NonDiskError}
  218.  
  219.  
  220. begin {procedure CEHandler}
  221.  
  222.  SetTextType(Rev);
  223.  CriticalErrorOccurred:=true;
  224.  AH:=hi(AX);
  225.  AL:=lo(AX);
  226.  if (AH and $80) = 0 then CriticalErrorCode:=DiskError
  227.  else CriticalErrorCode:=NonDiskError;
  228.  gotoxy (1,22); write (' Strike any key to continue             ');
  229.  ch:=ReadKey;
  230.  AX:=0;
  231.  SetTextType(Norm);
  232.  EraseWarning;
  233.  
  234. end; {procedure CEHandler}
  235. {$F-}
  236.  
  237. {------------------------------------------------ procedure ProcessIOError }
  238.  
  239. {
  240. purpose: to handle IO errors from within this program.
  241. }
  242.  
  243. procedure ProcessIOError(IOErrorCode:integer);
  244.  
  245. var
  246.  Msg:Str40;
  247.  Ch:char;
  248.  
  249. begin
  250.  if IOErrorCode=0 then exit;
  251.  case IOErrorCode of
  252.   {DOS errors}
  253.   2:Msg:=' File not found                          ';
  254.   3:Msg:=' Path not found                          ';
  255.   4:Msg:=' Too many open files                     ';
  256.   5:Msg:=' File access denied                      ';
  257.   6:Msg:=' Invalid file handle                     ';
  258.   7:Msg:=' Invalid file access code                ';
  259.   15:Msg:=' Invalid drive number                    ';
  260.   16:Msg:=' Cannot remove current directory         ';
  261.   17:Msg:=' Cannot rename accross drives            ';
  262.  
  263.   {Turbo Pascal IO Errors}
  264.   100:Msg:=' Disk read error                         ';
  265.   101:Msg:=' Disk write error                        ';
  266.   102:Msg:=' File not assigned                       ';
  267.   103:Msg:=' File not open                           ';
  268.   104:Msg:=' File not open for input                 ';
  269.   105:Msg:=' File not open for output                ';
  270.   106:Msg:=' Invalid numeric format                  ';
  271.  else
  272.   Msg:=' Unknown error                          ';
  273.  end; {case code of}
  274.  
  275.  SetTextType(Rev);
  276.  gotoxy(1,19); write (' I/O Error encountered.                 ');
  277.  Str(IOErrorCode:3,S);
  278.  S:=' Decimal Error IOErrorCode # '+S;
  279.  while length(S)<40 do S:=S+' ';
  280.  gotoxy(1,20); write (S);
  281.  SetTextType(RevBlink);
  282.  gotoxy(1,21); write (Msg);
  283.  SetTextType(Rev);
  284.  gotoxy(1,22); write (' Strike any key to continue.            ');
  285.  SetTextType(Norm);
  286.  Ch:=ReadKey;
  287.  EraseWarning;
  288. end; {procedure ProcessIOError}
  289.  
  290. {-------------------------------------------------- procedure CheckIOError }
  291.  
  292. {
  293. purpose: to determine if an IO error has occurred.
  294. }
  295.  
  296. procedure CheckIOError;
  297.  
  298. begin {procedure CheckIOError}
  299.  
  300.   IOErrorCode:=IOResult;
  301.   if IOErrorCode<>0 then ProcessIOError(IOErrorCode);
  302.  
  303. end; {procedure CheckIOError}
  304.  
  305. {-------------------------------------------------- procedure InvalidKey }
  306.  
  307. {
  308. purpose: to warn the user of invalid input or request.
  309. }
  310.  
  311. procedure InvalidKey;
  312.  
  313. begin {procedure InvalidKey}
  314.  
  315.   SetTextType(Rev);
  316.   gotoxy(1,18); write (' Invalid key ');
  317.   sound(300); delay(50);
  318.   sound(600); delay(50);
  319.   sound(1500); delay(50);
  320.   NoSound;
  321.   delay(50);
  322.   SetTextType(Norm);
  323.   EraseWarning;
  324.  
  325. end; {procedure InvalidKey}
  326.  
  327. {------------------------------------------------ procedure Click }
  328.  
  329. {
  330. purpose: to make a clicking sound.  This is sound is used as feedback
  331.          every time a counter key is pressed.  A different sound is
  332.          made if in subtraction mode.
  333. }
  334.  
  335. procedure click;
  336.  
  337. begin {procedure click}
  338.  
  339.   if add then
  340.   begin
  341.    Sound(750); delay(20);
  342.   end
  343.   else
  344.   begin
  345.    Sound(1250); delay(20);
  346.   end;
  347.   NoSound;
  348.  
  349. end; {procedure click}
  350.  
  351. {-------------------------------------------------- procedure CursorOff }
  352.  
  353. {
  354. purpose: to turn the cursor off.
  355. }
  356. procedure CursorOff;
  357.  
  358. begin {procedure CursorOff}
  359.  
  360.  regs.cx:=$2000;
  361.  regs.ax:=$0100;
  362.  intr($10,regs)
  363.  
  364. end; {procedure CursorOff}
  365.  
  366. {------------------------------------------------ procedure CursorOn }
  367.  
  368. {
  369. purpose: to turn the cursor on.
  370. }
  371.  
  372. procedure CursorOn;
  373.  
  374. begin {procedure CursorOn}
  375.  
  376.  if mem[0:$449]=7 then regs.cx:=$0C0D else regs.cx:=$0607;
  377.  regs.ax:=$0100;
  378.  intr($10,regs)
  379.  
  380. end; {procedure CursorOn}
  381.  
  382. {------------------------------------------------ procedure UpdateScreen }
  383.  
  384. {
  385. purpose: to update the screen when the status of a counter changes.
  386. }
  387.  
  388. procedure UpdateScreen(i:byte);
  389.  
  390. begin {procedure UpDateScreen}
  391.  
  392.  {derive the screen position to update}
  393.  if i<=10 then
  394.  begin
  395.   xpos:=33;
  396.   ypos:=i+6;
  397.  end
  398.  else
  399.  begin
  400.   xpos:=72;
  401.   ypos:=i-4;
  402.  end; {if i<=10}
  403.  SetTextType(High);
  404.  gotoxy(xpos,ypos); write (CharCounterArray[i]:5);
  405.  SetTextType(Norm);
  406. end; {procedure UpDateScreen}
  407.  
  408. {------------------------------------------------ function time }
  409.  
  410. {
  411. purpose: to retrieve the system's time.
  412. }
  413.  
  414. function time:str11;
  415.  
  416. var
  417.  hr,min,sec,hun:str2;
  418.  
  419. begin {function time:str11}
  420.  
  421.  GetTime(Hour,Minute,Second,Sec100);
  422.  str(Hour:2,hr);
  423.  str(Minute:2,min);
  424.  str(Second:2,sec);
  425.  str(Sec100:2,hun);
  426.  if hr[1]=' ' then hr[1]:='0';
  427.  if min[1]=' ' then min[1]:='0';
  428.  if sec[1]=' ' then sec[1]:='0';
  429.  if hun[1]=' ' then hun[1]:='0';
  430.  time:=hr+':'+min+':'+sec+'.'+hun;
  431.  
  432. end; {function time:str11}
  433.  
  434. {------------------------------------------------ function date }
  435.  
  436. {
  437. purpose: to retrieve the system's date.
  438. }
  439.  
  440. function date:str8;
  441.  
  442. var
  443.  Year,Month,Day,DayOfWeek:word;
  444.  yr,mon,dy:Str2;
  445.  yrstr:Str4;
  446.  
  447. begin {function date}
  448.  
  449.  GetDate(Year,Month,Day,DayOfWeek);
  450.  str(Year:4,yrstr);
  451.  yr:=copy(yrstr,3,2);
  452.  str(Month:2,mon);
  453.  str(Day:2,dy);
  454.  if mon[1]=' ' then mon[1]:='0';
  455.  if dy[1]=' ' then dy[1]:='0';
  456.  date:=mon+'/'+dy+'/'+yr;
  457. end; {function date}
  458.  
  459. {------------------------------------------------ procedure UpDateClock }
  460.  
  461. {
  462. purpose: to update the screen clock every minute.
  463. }
  464.  
  465. procedure UpDateClock;
  466.  
  467. var
  468.  TempTime,LastTime:str5;
  469.  
  470. begin {procedure UpDateClock}
  471.  
  472.  TempTime:=time;
  473.  if TempTime>LastTime then
  474.  begin
  475.   SetTextType(Rev);
  476.   gotoxy(74,1); write (TempTime);
  477.   SetTextType(Norm);
  478.   LastTime:=TempTime;
  479.  end;
  480.  
  481. end; {procedure UpDateClock}
  482.  
  483. {------------------------------------------------ function BuildStr }
  484.  
  485. {
  486. purpose: to build a string with n characters of ch.
  487. }
  488.  
  489. function BuildStr(c:Char; n:integer):str80;
  490.  
  491. var
  492.   S:str80;
  493.  
  494. begin {function BuildStr}
  495.   if n<0 then n:=0;
  496.   S[0]:=Chr(n);
  497.   FillChar(S[1],n,C);
  498.   BuildStr:=S;
  499.  
  500. end; {function BuildStr}
  501.  
  502. {------------------------------------------------ procedure MakeUpCase }
  503.  
  504. {
  505. purpose: to make a string into uppercase.
  506. }
  507.  
  508. procedure MakeUpCase (var S:Str80);
  509.  
  510. var
  511.   i:integer;
  512.  
  513. begin {procedure MakeUpCase}
  514.  
  515.   for i:=1 to Length(S) do
  516.   S[i]:=UpCase(S[i]);
  517.  
  518. end;  {procedure MakeUpCase}
  519.  
  520. {------------------------------------------------ procedure InputStr }
  521.  
  522. {
  523. purpose: to let user enter a string of length l at coordinates xpos,ypos.
  524. }
  525.  
  526. procedure InputStr(var S:Str80; l,xpos,ypos:byte);
  527.  
  528. const
  529.   Blank=' ';
  530.  
  531. var
  532.   p:byte;
  533.   ch:char;
  534.   done:boolean;
  535.  
  536. begin {procedure InputStr}
  537.  
  538.   done:=false;
  539.   CursorOn;
  540.   S:='';
  541.   SetTextType(Rev);
  542.   gotoxy(xpos,ypos);
  543.   write(S,BuildStr(Blank,l-length(S)));
  544.   p:=0;
  545.   repeat
  546.     gotoxy(xpos+p,ypos);
  547.     ch:=ReadKey;
  548.     case ch of
  549.       #0:begin  {dump extended keys}
  550.           ch:=ReadKey;
  551.           InvalidKey;
  552.           SetTextType(Rev);
  553.          end;
  554.       #32..#126:if p<l then
  555.                 begin
  556.                  if Length(S)=l then
  557.                   delete(S,l,1);
  558.                   p:=p+1;
  559.                   insert(ch,S,p);
  560.                   write(Copy(S,p,l));
  561.                 end
  562.                 else
  563.                 begin
  564.                  InvalidKey;
  565.                  SetTextType(Rev);
  566.                 end;
  567.         ^H,#127:if p>0 then
  568.                 begin
  569.                  delete(S,P,1);
  570.                  write(^H,Copy(S,P,L),Blank);
  571.                  p:=p-1;
  572.                 end
  573.                 else
  574.                 begin
  575.                  InvalidKey;
  576.                  SetTextType(Rev);
  577.                 end;
  578.         #13,#27:done:=true;
  579.     else
  580.     begin
  581.      InvalidKey;
  582.      SetTextType(Rev);
  583.     end;
  584.     end;  {of case}
  585.   until done;
  586.   if ch=#27 then S:='';
  587.   p:=Length(S);
  588.   gotoxy(xpos+p,ypos);
  589.   write('' :l-p);
  590.   SetTextType(High);
  591.   gotoxy(xpos,ypos); write (BuildStr(Blank,l));
  592.   gotoxy(xpos,ypos); write (S);
  593.   SetTextType(Norm);
  594.   CursorOff;
  595. end; {procedure InputStr}
  596.  
  597. {------------------------------------------------ procedure HitKey }
  598.  
  599. {
  600. purpose: to determine which key has been hit.
  601. }
  602.  
  603. procedure HitKey (KeyList:Str20; var Key1,Key2:char);
  604.  
  605. begin {procedure HitKey}
  606.  
  607.  Key2:=chr(0);
  608.  repeat
  609.   Key1:=ReadKey;
  610.   if (Key1=#0) then Key2:=ReadKey;
  611.   if length(KeyList)=0 then exit;
  612.   if (pos(Key1,KeyList)=0) then InvalidKey;
  613.  until pos(Key1,KeyList)>0;
  614.  
  615. end; {procedure HitKey}
  616.  
  617. {------------------------------------------------ proceure ChangePath }
  618.  
  619. {
  620. purpose: to change the active path.
  621. }
  622.  
  623. procedure ChangePath(var ActivePath:Str67);
  624.  
  625. var
  626.  ch,LastChar:Char;
  627.  TempPath:Str67;
  628.  
  629. begin {procedure ChangePath}
  630.  
  631. gotoxy(1,18); clreol; write (' Enter new active path : ');
  632. InputStr(S,67,2,19);
  633. MakeUpCase(S);
  634.  
  635. if Length(S)=0 then
  636. begin
  637.  EraseWarning;
  638.  exit;
  639. end;
  640.  
  641. LastChar:=S[Length(S)];
  642. if ((length(S)>3) and (LastChar='\')) then Delete(S,length(S),1);
  643. if ((length(S)=2) and (LastChar=':')) then S:=S+'\';
  644.  
  645. TempPath:=S;
  646.  
  647. {check for valid requested path}
  648. ChDir(TempPath);
  649. IOErrorCode:=IOResult;
  650.  
  651. {check for critical error}
  652. if CriticalErrorOccurred then
  653. begin
  654.  {restore previous path before exiting}
  655.  ChDir(ActivePath);
  656.  {reset error flags}
  657.  IOErrorCode:=IOResult;
  658.  CriticalErrorOccurred:=false;
  659.  exit;
  660. end; {if CriticalErrorOccurred}
  661.  
  662. {check for IO Error}
  663. if IOErrorCode<>0 then
  664. begin
  665.  ProcessIOError(IOErrorCode);
  666.  {restore the previous ActivePath before exiting}
  667.  ChDir(ActivePath);
  668.  {reset error flags}
  669.  IOErrorCode:=IOResult;
  670.  CriticalErrorOccurred:=false;
  671.  exit;
  672. end
  673. else
  674. begin
  675.  ActivePath:=TempPath;
  676.  if length(ActivePath)>3 then ActivePath:=ActivePath+'\';
  677. end; {if IOErrorCode<>0}
  678.  
  679. gotoxy(1,2); clreol; write ('Active path : ');
  680. SetTextType(High); write (ActivePath); SetTextType(Norm);
  681.  
  682. end; {procedure ChangePath}
  683.  
  684. {-------------------------------------------------- function PrinterOk }
  685.  
  686. {
  687. purpose: to determine if the printer is on line.
  688. }
  689.  
  690. function PrinterOK:boolean;
  691.  
  692. var
  693.  ch:char;
  694.  
  695. begin {function PrinterOK}
  696.  
  697.  regs.dx:=$0000;
  698.  regs.ax:=$0200;
  699.  intr($17,regs);
  700.  if (odd(hi(regs.ax shr 3)) or (not(odd(hi(regs.ax shr 7))))) then
  701.   PrinterOK:=false else PrinterOK:=true;
  702.  
  703. end; {function PrinterOK}
  704.  
  705. {------------------------------------------------ function ValidFileName }
  706.  
  707. {
  708. purpose: to get a valid filename from the user.
  709. }
  710.  
  711. function ValidFileName:boolean;
  712.  
  713. var
  714.  PeriodPosition,i:integer;
  715.  Name:Str8;
  716.  Ext:Str3;
  717.  ch:char;
  718.  ValidName:boolean;
  719.  
  720. begin {function ValidFileName}
  721.  
  722.  Name:='';
  723.  Ext:='';
  724.  ValidName:=true;
  725.  
  726.  gotoxy(1,18); clreol; write (' Enter a file name : ');
  727.  InputStr(S,12,22,18);
  728.  MakeUpCase(S);
  729.  EraseWarning;
  730.  
  731.  if length(S)=0 then ValidName:=false
  732.  else
  733.  begin
  734.  
  735.   {check for position of .}
  736.   PeriodPosition:=Pos('.',S);
  737.  
  738.   if PeriodPosition<>0 then
  739.   begin
  740.    Name:=Copy(S,1,PeriodPosition-1);
  741.    Ext:=Copy(S,PeriodPosition+1,(length(S)-length(Name)+1));
  742.   end
  743.   else Name:=S;
  744.  
  745.   {check the filename for invalid characters}
  746.   for i:=1 to length(Name) do
  747.   begin
  748.  
  749.    {filename cannot begin with a number}
  750.    if ((i=1) and (ord(Name[i]) IN [48..57])) then ValidName:=false;
  751.    {check for other forbidden characters in the filename}
  752.    if (ord(Name[i]) IN [0..32,34,46,47,92,91,93,58,124,62,60,43,61,59,44]) then
  753.     ValidName:=false;
  754.  
  755.   end; {for i:=1 to}
  756.  
  757.   {check the extension for ivalid characters}
  758.   if Ext<>'' then
  759.   begin
  760.    for i:=1 to length(Ext) do
  761.    begin
  762.     {check for forbidden characters in the file extension}
  763.     if (ord(Ext[i]) IN [0..32,34,46,47,92,91,93,58,124,62,60,43,61,59,44]) then
  764.      ValidName:=false;
  765.  
  766.    end; {for i:=1 to length(Ext)}
  767.   end; {if Ext<>'' then}
  768.  end; {if length(S)=0...}
  769.  
  770.  if not ValidName then
  771.  begin
  772.   ValidFileName:=false;
  773.   FileName:='';
  774.   SetTextType(RevBlink);
  775.   gotoxy(1,20); write (' Illegal character(s) in file name.');
  776.   SetTextType(Rev);
  777.   gotoxy(1,21); write (' Strike any key to continue.       ');
  778.   SetTextType(Norm);
  779.   ch:=ReadKey;
  780.  end
  781.  else
  782.  begin
  783.   ValidFileName:=true;
  784.  
  785.   {reconstitute the filename}
  786.   if Ext<>'' then FileName:=Name+'.'+Ext else FileName:=Name;
  787.  
  788.  end; {if not ValidName then}
  789.  
  790.  EraseWarning;
  791.  
  792. end; {function ValidFileName}
  793.  
  794. {------------------------------------------------ procedure OpenOutPutFile }
  795.  
  796. {
  797. purpose: to open a file for output.
  798. }
  799.  
  800. procedure OpenOutPutFile;
  801.  
  802. var
  803.  ch:char;
  804.  
  805. begin {procedure OpenOutPutFile}
  806.  
  807.  {prompt the user for a filename}
  808.  if not ValidFileName then exit;
  809.  
  810.  {check if file already exists, if so overwrite?}
  811.  ActiveFile:=FileName;
  812.  PathFileName:=ActivePath+ActiveFile;
  813.  
  814.  Assign(OutPutFile,PathFileName);
  815.  Reset(OutPutFile);
  816.  
  817.  {if IOResult=0 file already exists, should it be overwritten?}
  818.  if IOResult=0 then
  819.  begin
  820.   SetTextType(Rev);
  821.   gotoxy(1,18); write (' File already exists.  Overwrite? (Y/N) ');
  822.   ch:=ReadKey;
  823.   SetTextType(Norm);
  824.   EraseWarning;
  825.   if ((ch) IN ['N','n']) then
  826.   begin
  827.    {release the file handle and exit}
  828.    Close(OutPutFile);
  829.    exit;
  830.   end; {if ((ch) IN ['N','n'])}
  831.  end; {if IOResult=0}
  832.  
  833.  Rewrite(OutPutFile);
  834.  IOErrorCode:=IOResult;
  835.  if IOErrorCode<>0 then
  836.  begin
  837.   ProcessIOError(IOErrorCode);
  838.   exit;
  839.  end; {if IOErrorCode<>0}
  840.  
  841.  SetTextType(High);
  842.  gotoxy(15,1);
  843.  write ('             ');
  844.  gotoxy(15,1);
  845.  write (ActiveFile);
  846.  SetTextType(Norm);
  847.  OutPutFileOpen:=true;
  848.  
  849. end; {procedure OpenOutPutFile}
  850.  
  851. {------------------------------------------------ procedure PrinterDump }
  852.  
  853. {
  854. purpose: to send output to the printer and to advance the page when
  855.          necessary.
  856. }
  857.  
  858. procedure PrinterDump (S:Str80);
  859.  
  860. begin {procedure PrinterDump}
  861.  
  862.   if PrinterLine>=65 then
  863.   begin
  864.    writeln (lst,#12);
  865.    PrinterLine:=1;
  866.   end; {if PrinterLine>=65}
  867.   writeln (lst,S);
  868.   PrinterLine:=PrinterLine+1;
  869.  
  870. end; {procedure PrinterDump}
  871.