home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
pibterm
/
pibt41s1.arc
/
DOSJUMP.MOD
< prev
next >
Wrap
Text File
|
1988-02-13
|
13KB
|
355 lines
(*----------------------------------------------------------------------*)
(* SetBlock --- Free up some memory above this program for DOS shell *)
(*----------------------------------------------------------------------*)
FUNCTION SetBlock( VAR Paragraphs : WORD ) : BOOLEAN;
VAR
Regs : Registers;
BEGIN (* SetBlock *)
WITH Regs DO
BEGIN
(* Use DOS function $4A to release *)
(* memory *)
AH := $4A;
ES := PrefixSeg;
BX := Paragraphs;
MSDOS( Regs );
Paragraphs := BX;
SetBlock := ( NOT ODD( Flags ) );
END;
END (* SetBlock *);
(*----------------------------------------------------------------------*)
(* DosExec -- Execute a DOS command or DOS shell *)
(*----------------------------------------------------------------------*)
FUNCTION DosExec( Command : AnyStr ) : INTEGER;
VAR
ComSpecStr : AnyStr;
OldHeapEnd : POINTER;
SizeOfFreeList : WORD;
ParasToKeep : WORD;
ParasWeHave : WORD;
ParasForDos : WORD;
M : WORD;
(*----------------------------------------------------------------------*)
(* SubtractPointers -- Find # of bytes between two pointer addresses *)
(*----------------------------------------------------------------------*)
FUNCTION SubtractPointers( High_Pointer : POINTER;
Low_Pointer : POINTER ) : LONGINT;
BEGIN (* SubtractPointers *)
SubtractPointers := ( LONGINT( SEG( High_Pointer^ ) ) SHL 4 +
OFS( High_Pointer^ ) ) -
( LONGINT( SEG( Low_Pointer^ ) ) SHL 4 +
OFS( Low_Pointer^ ) );
END (* SubtractPointers *);
(*----------------------------------------------------------------------*)
(* HeapEnd --- Return pointer to end of heap *)
(*----------------------------------------------------------------------*)
FUNCTION HeapEnd : POINTER;
BEGIN (* HeapEnd *)
IF ( OFS( FreePtr^ ) = 0 ) THEN
(* Free list is empty -- add *)
(* $1000 to the segment. *)
HeapEnd := PTR( SEG( FreePtr^ ) + $1000 , 0 )
ELSE
HeapEnd := PTR( SEG( FreePtr^ ) + ( OFS( FreePtr^ ) SHR 4 ) , 0 );
END (* HeapEnd *);
(*----------------------------------------------------------------------*)
BEGIN (* DosExec *)
(* Calculate # bytes to save *)
SizeOfFreeList := SubtractPointers( HeapTop , HeapEnd );
(* Check for sufficient memory in *)
(* unused file transfer buffer to *)
(* save free list *)
IF ( MaxSectorLength < LONGINT( SizeOfFreeList ) ) THEN
BEGIN
(* Not enough memory to store free list *)
DosExec := -1;
EXIT;
END;
(* Save current pointer to end of *)
(* free list *)
OldHeapEnd := HeapEnd;
(* Get current DOS memory allocation *)
(* from memory control block *)
ParasWeHave := MemW[ PRED( PrefixSeg ) : 3 ];
(* Calculate amount of memory to give up *)
ParasForDos := PRED( SubtractPointers( HeapTop , HeapPtr ) SHR 4 );
(* Calculate amount of memory to keep *)
(* while in shell *)
ParasToKeep := ParasWeHave - ParasForDos;
(* See if enough memory to run DOS *)
IF ( ( ParasForDos > 0 ) AND
( ParasForDos < ( MinSpaceForDos SHR 4 ) ) ) THEN
BEGIN
DosExec := -4;
EXIT;
END;
(* Deallocate memory for DOS *)
IF ( NOT SetBlock( ParasToKeep ) ) THEN
BEGIN
DosExec := -2;
EXIT;
END;
(* Build the Command string *)
ComSpecStr := GetEnvStr( 'COMSPEC' );
IF ( LENGTH( Command ) > 0 ) THEN
Command := '/C ' + Command;
M := ( ParasForDos - 240 ) SHR 6;
WRITELN('Approximate memory available: ', M, 'K');
(* Save free list *)
MOVE( OldHeapEnd^, Sector_Data, SizeOfFreeList );
(* Call Turbo's EXEC function *)
EXEC( ComSpecStr , Command );
(* Reallocate memory from DOS *)
IF ( NOT SetBlock( ParasWeHave ) ) THEN
BEGIN
DosExec := -3;
EXIT;
END;
(* Restore free list *)
MOVE( Sector_Data, OldHeapEnd^, SizeOfFreeList );
(* Function result is in DosError *)
DosExec := DosError;
END (* DosExec *);
(*----------------------------------------------------------------------*)
(* DosJump --- Jump to Dos *)
(*----------------------------------------------------------------------*)
PROCEDURE DosJump( Dos_String : AnyStr );
(*----------------------------------------------------------------------*)
(* *)
(* Procedure: DosJump; *)
(* *)
(* Purpose: Provides facility for jumping to DOS *)
(* *)
(* Calling Sequence: *)
(* *)
(* DosJump( Dos_String : AnyStr ); *)
(* *)
(* Dos_String --- DOS command to execute *)
(* *)
(* Calls: *)
(* *)
(* DosExec *)
(* Open_For_Append *)
(* *)
(*----------------------------------------------------------------------*)
VAR
I : INTEGER;
Ierr : INTEGER;
Local_Save : Saved_Screen_Ptr;
Open_Flag : BOOLEAN;
Save_Cursor : INTEGER;
Save_Status : BOOLEAN;
Save_Video : BOOLEAN;
Save_Border : INTEGER;
Save_VidMode : INTEGER;
Save_Int1B : POINTER;
BEGIN (* DosJump *)
(* Save screen contents. Note that *)
(* EGA contents must actually be *)
(* saved this time. *)
{
Really_Save_EGA := TRUE;
}
Save_Screen( Local_Save );
Save_VidMode := Current_Video_Mode;
PibTerm_Window( 1, 1, Max_Screen_Col, Max_Screen_Line );
Scroll( 1, Max_Screen_Line, 1, Max_Screen_Col, 0,
LightGray, Black );
Save_Border := Global_Border_Color;
Set_Border_Color( Black );
GoToXY( 1 , 1 );
Save_Status := Do_Status_Time;
Do_Status_Time := FALSE;
IF ( LENGTH( Dos_String ) = 0 ) THEN
BEGIN
WRITELN;
WRITELN('Jump to DOS: Enter EXIT to return to PibTerm');
END;
(* Turn off extended keypad *)
IF Extended_Keypad THEN
Remove_Keyboard_Handler;
(* Turn off video handler *)
Save_Video := Video_Handler_Installed;
IF Save_Video THEN
Remove_Video_Handler;
(* Close capture file *)
IF Capture_On THEN
(*!I-*)
CLOSE( Capture_File );
(*!I+*)
(* Close log file *)
IF Log_File_Open THEN
(*!I-*)
CLOSE( Log_File );
(*!I+*)
I := Int24Result;
(* Remove Int 24 error handler *)
Int24OFF( FALSE );
(* Close communications if requested *)
IF Close_Comm_For_Dos THEN
Async_Close( FALSE );
(* Change cursor to block *)
IF ( Font8x8Loaded OR ( Current_Video_Mode <> 7 ) ) THEN
CursorSet( $0107 )
ELSE
CursorSet( $010D );
(* Allow <CTRL>Break checking *)
GetIntVec( $1B , Save_Int1B );
SetIntVec( $1B , SaveInt1B );
(* Jump to DOS *)
Ierr := DosExec( Dos_String );
(* Disallow <CTRL>Break checking *)
SetIntVec( $1B , Save_Int1B );
(* Restore previous video mode *)
IF ( Current_Video_Mode <> Save_VidMode ) THEN
Set_Text_Mode( Save_VidMode );
(* Reset EGA if needed *)
IF EGA_Present THEN
Set_EGA_Text_Mode( Max_Screen_Line );
(* Change cursor back to underline *)
CursorOn;
(* Restore Int24 Error handler *)
Int24ON;
(* Restore communications. Port *)
(* opened twice in case major *)
(* weirdness causes first open *)
(* to screw up. *)
IF Close_Comm_For_Dos THEN
FOR I := 1 TO 2 DO
Open_Flag := Async_Open( Comm_Port, Baud_Rate, Parity, Data_Bits,
Stop_Bits )
ELSE
Async_Clear_Errors;
CASE Ierr OF
-1: WRITELN('Not enough memory to store free list, DOS jump cannot be done');
-2: WRITELN('Set Block error, DOS jump cannot be done');
-3: BEGIN
{
WRITELN('Set Block error on return from DOS, PibTerm cannot continue.');
WRITELN('You will probably need to re-boot.');
}
Halt( BadDosJump );
END;
-4: WRITELN('Not enough memory to jump to DOS');
ELSE
WRITELN('Back to PibTerm, DOS return code is ',Ierr);
END (* CASE *);
(* Reopen capture file for append *)
IF Capture_On THEN
BEGIN
IF ( NOT Open_For_Append( Capture_File , Capture_File_Name , I ) ) THEN
BEGIN
WRITELN('Can''t re-open capture file ',
Capture_File_Name);
WRITELN('Capture option TURNED OFF.');
Capture_On := FALSE;
Window_Delay;
END;
END;
(* Reopen log file for append *)
IF Logging_On THEN
Log_File_Open := Open_For_Append( Log_File,
Log_File_Name, I );
(* Log this jump to DOS *)
Write_Log('Jump to DOS : ' + Dos_String, FALSE, FALSE );
Write_Log(' Return Code: ' + IToS( Ierr ), TRUE, FALSE );
(* If we got here from Alt-J, *)
(* or request for shell in *)
(* script, then wait for a key *)
(* to be struck. *)
{
IF ( LENGTH( Dos_String ) = 0 ) OR
( ( ( Err <> 0 ) OR ( Ierr <> 0 ) ) AND Attended_Mode ) AND
( NOT Host_Mode ) THEN
Press_Any;
}
(* Restore screen contents *)
Restore_Screen_And_Colors( Local_Save );
Set_Border_Color( Save_Border );
(* Restore status line updating *)
Do_Status_Time := Save_Status;
(* Restore extended keyboard *)
IF Extended_Keypad THEN
Install_Keyboard_Handler;
(* Restore video handler *)
IF Save_Video THEN
Install_Video_Handler;
(* Turn off save EGA flag *)
{
Really_Save_EGA := FALSE;
}
END (* DosJump *);