home *** CD-ROM | disk | FTP | other *** search
- PROGRAM Arcitlbr;
-
- {------------------------------------------------------------------------------
- PROGRAM ARCITLBR 1.00A 02/01/86
- BY Karson W. Morrison Caleb Computing Center
- RD1 Box 531 Ringoes NJ 08551
- 201-788-1846
-
- This program is executed as part of the ARCIT.BAT when a library file
- is squeezed. i.e. *.lqr. The program, amd batch file as originally
- issued worked fine except when there was a numeric number as part of
- the library name and the basic program went into the wild blue yonder.
- This program uses the ability of Turbo pascal to execute other programs.
-
- I execute program LU a XXXXXX.LBR
- Then I execute program DEL XXXXXX.LBR
-
- When this program is compiled you must make the maxavailable memory
- to 0400, or the program will not run. This is done in the options
- section of TURBO PASCAL.
- ------------------------------------------------------------------------------}
- {$I-,U-,C-}
-
-
-
- Type
- Str66=String[66];
- Str255=String[255];
- registers = record { register pack used in MSDos call }
- ax, bx, cx, dx, bp, si, di, ds, es, flags : integer;
- end;
- char80arr = array [ 1..80 ] of char;
- string80 = string[ 80 ];
-
-
- VAR { VARIABLE declarations }
- DTA : array [ 1..43 ] of byte; { Data Transfer Area buffer }
- DTAseg, { DTA segment before exicution }
- DTAofs, { DTA offset " " }
- setDTAseg, { DTA segment and offset set after }
- setDTAofs, { start of program }
- error, { error return }
- i, j, { used as counters }
- option : integer; { used to specify file types }
- regs : registers; { register pack for the DOS call }
- FilVar : text;
- space : integer;
- buffer, { generic buffer }
- namr : string80; { file name }
- mask : char80arr; { file mask }
-
- Command: Str255;
-
-
- Function SubProcess(CommandLine: Str255): Integer;
-
- Const
- SSSave: Integer=0;
- SPSave: Integer=0;
-
- Var
- Regs: Record Case Integer Of
- 1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
- 2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
- End;
- FCB1,FCB2: Array [0..36] Of Byte;
- PathName: Str66;
- CommandTail: Str255;
- ParmTable: Record
- EnvSeg: Integer;
- ComLin: ^Integer;
- FCB1Pr: ^Integer;
- FCB2Pr: ^Integer;
- End;
- I,RegsFlags: Integer;
-
- Begin
- If Pos(' ',CommandLine)=0 Then
- Begin
- PathName:=CommandLine+#0;
- CommandTail:=^M;
- End
- Else
- Begin
- PathName:=Copy(CommandLine,1,Pos(' ',CommandLine)-1)+#0;
- CommandTail:=Copy(CommandLine,Pos(' ',CommandLine),255)+^M;
- End;
- CommandTail[0]:=Pred(CommandTail[0]);
- With Regs Do
- Begin
- FillChar(FCB1,Sizeof(FCB1),0);
- AX:=$2901;
- DS:=Seg(CommandTail[1]);
- SI:=Ofs(CommandTail[1]);
- ES:=Seg(FCB1);
- DI:=Ofs(FCB1);
- MsDos(Regs); { Create FCB 1 }
- FillChar(FCB2,Sizeof(FCB2),0);
- AX:=$2901;
- ES:=Seg(FCB2);
- DI:=Ofs(FCB2);
- MsDos(Regs); { Create FCB 2 }
- ES:=CSeg;
- BX:=SSeg-CSeg+MemW[CSeg:MemW[CSeg:$0101]+$112];
- AH:=$4A;
- MsDos(Regs); { Deallocate unused memory }
- With ParmTable Do
- Begin
- EnvSeg:=MemW[CSeg:$002C];
- ComLin:=Addr(CommandTail);
- FCB1Pr:=Addr(FCB1);
- FCB2Pr:=Addr(FCB2);
- End;
- InLine($8D/$96/ PathName /$42/ { <DX>:=Ofs(PathName[1]); }
- $8D/$9E/ ParmTable / { <BX>:=Ofs(ParmTable); }
- $B8/$00/$4B/ { <AX>:=$4B00; }
- $1E/$55/ { Save <DS>, <BP> }
- $16/$1F/ { <DS>:=Seg(PathName[1]); }
- $16/$07/ { <ES>:=Seg(ParmTable); }
- $2E/$8C/$16/ SSSave / { Save <SS> in SSSave }
- $2E/$89/$26/ SPSave / { Save <SP> in SPSave }
- $FA/ { Disable interrupts }
- $CD/$21/ { Call MS-DOS }
- $FA/ { Disable interrupts }
- $2E/$8B/$26/ SPSave / { Restore <SP> }
- $2E/$8E/$16/ SSSave / { Restore <SS> }
- $FB/ { Enable interrupts }
- $5D/$1F/ { Restore <BP>,<DS> }
- $9C/$8F/$86/ RegsFlags / { Flags:=<CPU flags> }
- $89/$86/ Regs ); { Regs.AX:=<AX>; }
- If (RegsFlags And 1)<>0 Then SubProcess:=AX
- Else SubProcess:=0;
- End;
- End;
-
- Function GetComSpec: Str66;
- Type
- Env=Array [0..32767] Of Char;
- Var
- EPtr: ^Env;
- EStr: Str255;
- Done: Boolean;
- I: Integer;
-
- Begin
- EPtr:=Ptr(MemW[CSeg:$002C],0);
- I:=0;
- Done:=False;
- EStr:='';
- Repeat
- If EPtr^[I]=#0 Then
- Begin
- If EPtr^[I+1]=#0 Then Done:=True;
- If Copy(EStr,1,8)='COMSPEC=' Then
- Begin
- GetComSpec:=Copy(EStr,9,100);
- Done:=True;
- End;
- EStr:='';
- End
- Else EStr:=EStr+EPtr^[I];
- I:=I+1;
- Until Done;
- End;
-
- {------------------------------------------------------------------------------
- SetDTA resets the current DTA to the new address specified in the
- parameters 'SEGMENT' and 'OFFSET'.
- ------------------------------------------------------------------------------}
-
- PROCEDURE SetDTA( segment, offset : integer; var error : integer );
-
- BEGIN
- regs.ax := $1A00; { Function used to set the DTA }
- regs.ds := segment; { store the parameter segment in DS }
- regs.dx := offset; { " " " offset in DX }
- MSDos( regs ); { Set DTA location }
- error := regs.ax and $FF; { get error return }
- END;
-
- {------------------------------------------------------------------------------
- GetCurrentDTA is used to get the current Disk Transfer Area ( DTA )
- address. A function code of $2F is stored in the high byte of the AX
- register and a call to the predefined procedure MSDos is made. This can
- also be accomplished by using the "Intr" procedure with the same register
- record and a $21 specification for the interrupt.
- ------------------------------------------------------------------------------}
-
- PROCEDURE GetCurrentDTA( var segment, offset : integer;
- var error : integer );
-
- BEGIN
- regs.ax := $2F00; { Function used to get current DTA address }
- { $2F00 is used instead of $2F shl 8 to save
- three assembly instructions. An idea for
- optimization. }
- MSDos( regs ); { Exicute MSDos function request }
- segment := regs.es; { Segment of DTA returned by DOS }
- offset := regs.bx; { Offset of DTA returned }
- error := regs.ax and $FF;
- END;
-
- {------------------------------------------------------------------------------
- GetFirst gets the first directory entry of a particular file mask. The
- mask is passed as a parameter 'mask' and, the option was previosly specified
- in the SpecifyOption procedure.
- ------------------------------------------------------------------------------}
-
- PROCEDURE GetFirst( mask : char80arr; var namr : string80;
- segment, offset : integer; option : integer;
- var error : integer );
-
- VAR
- i : integer;
-
- BEGIN
- error := 0;
- regs.ax := $4E00; { Get first directory entry }
- regs.ds := seg( mask ); { Point to the file mask }
- regs.dx := ofs( mask );
- regs.cx := option; { Store the option }
- MSDos( regs ); { Exicute MSDos call }
- error := regs.ax and $FF; { Get error return }
- i := 1; { initialize 'i' to the first element }
- Repeat { Enter the loop that reads in the }
- { first file entry }
- namr[ i ] := chr( mem[ segment : offset + 29 + i ] );
- i := i + 1;
- Until ( not ( namr[ i - 1 ] in [ ' '..'~' ] ));
- namr[ 0 ] := chr( i - 1 ); { set string length because assigning }
- { by element does not set length }
- END;
-
-
-
- BEGIN { Begin Main Program }
- For i := 1 to 21 Do DTA[ i ] := 0; { Initialize the DTA buffer }
- For i := 1 to 80 Do { Initialize the mask and }
- Begin { file name buffers }
- mask[ i ] := chr( 0 );
- namr[ i ] := chr( 0 );
- End;
- namr[ 0 ] := chr( 0 ); { Set the file name length to 0 }
- Option := 1;
- writeln( 'ARCIT Un-LBR version 1.00A 2-1-1986' );
- writeln(' Written by Karson W. Morrison Caleb Computing Company');
- Writeln(' Rd 1 Box 531 Ringoes NJ. 08551 201-788-1846');
- error := 0;
- buffer[ 0 ] := chr( 0 ); { Set buffer length to 0 }
- buffer := '????????.LBR'; { then use global search }
- For i := 1 to length( buffer ) Do { Assign buffer to mask }
- mask[ i ] := buffer[ i ];
- While ( error = 0 ) Do
- Begin
- GetCurrentDTA( DTAseg, DTAofs, error ); { Get the current DTA address }
- If ( error <> 0 ) then { Check for errors }
- Begin { If yes then inform user }
- writeln( 'Unable to get current DTA' );
- writeln( 'Program aborting.' ); { and abort. }
- Halt; { End program now }
- End;
- setDTAseg := seg( DTA );
- setDTAofs := ofs( DTA );
- SetDTA( setDTAseg, setDTAofs, error ); { Reset DTA addresses }
- If ( error <> 0 ) then
- Begin { Check for errors }
- writeln( 'Cannot reset DTA' ); { Error message }
- writeln( 'Program aborting.' );
- Halt; { End program }
- End;
-
- { Normally you would do one GetFirst and the rest would be GetNext
- however because I am executing other programs the DTA is getting screwed
- up so I use GetFirst all the time. I am also deleting the file that
- I found the first time so I don't read it again. }
-
- GetFirst( mask, namr, setDTAseg, setDTAofs, option, error );
- If ( error = 0 ) then
- Begin
- for i := 1 to 9 do
- begin
- space := pos(' ',namr);
- if space > 0 then
- delete(namr,space,1);
- end;
- Command:=GetComSpec+' /C '+'LU A ' + namr;
- I:=SubProcess(Command);
- If I<>0 Then WriteLn('Error - ',I);
- Command:=GetComSpec+' /C '+ 'DEL ' + namr;
- I:=SubProcess(Command);
- If I<>0 Then WriteLn('Error - ',I);
- error := 0;
- end;
- End;
- END. { End Main }