home *** CD-ROM | disk | FTP | other *** search
- {$C-}
- {-----------------------------------------------------------------------------}
- { }
- { }
- { " S o r r y , D a v e, I C a n ' t D o T h a t . " }
- { }
- { Arthur C. Clark }
- { " 2 0 0 1 " }
- {-----------------------------------------------------------------------------}
- { Stayres Version 3.31
-
- { A Turbo "stay-resident" program clobbers the Dos register stack. It
- jumps over the Turbo run-time initialization code that would set up the
- program registers and environment. Secondly, a stay-resident program
- could not ordinarily issue file I/O since that would clobber Dos interrupt
- registers. Therefore, the following code proposes an inline solution,
- providing a Turbo entry stack for "stay-resident" programs and allowing
- those programs to issue Dos I/O and other interrupts.
-
- This Turbo stay-resident program will perform both Dos I/O
- and Bios interrupts. It has been tested for re-entrancy and recursiveness
- on an IBM PC with PCDOS 2.1, 3.1 .
-
- R_U_N I_N_S_T_R_U_C_T_I_O_N_S
- Execute the command file and activate with the default
- Alt-F1 key. It will also free its memory and return to Dos with the
- Ctrl-Home key at the last "Press a key" prompt (Illustrated in the Stayxit
- file). Maximum free dynamic memory should be between 300-400 paragraphs
- since this it uses a recursive stack. If you get $FF runtime errors or
- "allocation error", "cannot load Command.Com", then raise the mAximum
- free value to something reasonable but less than your maximum memory -
- 20K. This program can ONLY run as a COM file.
-
- For those of you already using user interrupts 60-67, please change the
- User_Int constant to an interrupt number you do not currently use .
-
- The Hunter's Helper
-
- Lane Ferris
- 4268 26th St
- San Francisco,Ca. 94131
- [ 70357,2716 ]
- }
- {-----------------------------------------------------------------------------}
- { This code has been tested/used on an IBM PC using PC-DOS 2.10/3.1 }
- {-----------------------------------------------------------------------------}
- { Authors: Lane H. Ferris (Stay Resident/Exit Code) }
- { Lynn A. Canning (Screen Counter }
- { Lynn A. Canning & Karson Morrison (Set Epson Printer}
- { Lynn A. Canning (Pgm-Aide Driver }
- { Other Public Gurus on whose shoulders we stand.}
- {
- PURPOSE: This code will serve as a template to create other "Stay Resident"
- programs in Turbo Pascal(tm). This code intercepts Int 16,
- displacing original Interrupt 16 Vector to User Interrupt 60.
- During execution of other programs, it can be invoked by the
- special key combination specified by "Our_Char" (in this case
- Alt-F1.)
-
- Modifications:
- 7. 7.85 - Replace Windows with a more simple form/less code.
- 7. 8.85 - Replace Window Array with Pointers/Heap form.
- 7.11.85 - Re-issue termination Keyboard Read / pass back to user
- Would like to back up Instruction Ptr by two bytes before
- the Int 16 ($CD16) but it might be a "long call" by
- some other Kbd interceptor (chirp chirp chrip)... and
- thats "trouble in River City".
- 7.19.85 - Clean up RmWin "incorrect" attribute bugs. If screen
- isnt cleared, we get border attribute, not text attrb.
- - Remove last window at Termination Time (Ctrl-Home).
- 8.26.85 - Version 3.10 Changes
- 1) Save 40 words in StaySave/Rstr to avoid clobbering
- Dos Stack when entering Dos with Turbo Write(ln) caused
- by Int 21 Function 5 (Writln(Lst,..)) which re-issues
- Int 16.
- 2) Change Int 68 to Int 67 to Avoid collisions with
- Dos 3.1 on an AT.
- 3) Correct "Press a Key..." to accept any "Key..."
- (not just Cr).
- 4) Check Int16 function. Jmp directly to Int16 if not
- a character request. Avoids 40 word Save/Restore
- overhead.
- 9.04.85 - Version 3.20 changes
- When returning to user program, pass back a fake
- "Ctrl-key" scan code to allow immediate re-execution
- of the TSR (Terminate Stay Resident) program. Also
- solves SideKick incessant bird caws.
- 9.18.85 - Version 3.2C
- When saving/restoring the stack, save 40 words or less
- depending on stack size (0-Sp = stack size) to avoid
- overflowing into SS:0 when stack is less than 40 words.
- Put back the "wait for user key logic" at program end.
- Beep like SuperKick if Key is OurKey
- Version 3.31
- 9.19.85 Futz around with the "wait for user key logic", allow
- the Our_key to pass, but beep user to show we aint
- gonna activate, cuz our InUse bit is still set.
- Clean up the documentation and duplicate instructions in
- StaySave/Rstr.
- Change Int67 to Int60 for Fun and Profit and get around
- Mark Stanock's use of those locations.
- }
- Program Stay_Resident;
-
- { * * * * * * * CONSTANTS * * * * * * * * * * * * * * * * * * * * * * }
- const
- Our_Char = 104; {this is the scan code for AltF1}
- Ctrl_Home = #119; {Control Home Scan Code }
- Quit_Key = #119;
- Ctrl_End = #117; {Control End Scan Code }
- User_Int = $60; {place to put new interrupt}
- Kybrd_Int = $16; {BIOS keyboard interrupt}
- MaxWin = 3; { Max number of windows open at one time }
-
- { - - - - - - T Y P E D E C L A R A T I O N S - - - - - - - - - - - - }
- Type
- Regtype = record Ax,Bx,Cx,Dx,Bp,Si,Di,Ds,Es,Flags:integer end;
- HalfRegtype = record Al,Ah,Bl,Bh,Cl,Ch,Dl,Dh:byte end;
- filename_type = string[64];
-
- { - - - - - - - T Y P E D C O N S T A N T S - - - - - - - - - - - - - - -}
- Const
- {regs is defined as a typed constant in order to get it in the code segment}
-
- Regs : regtype = (Ax:0;Bx:0;Cx:0;Dx:0;Bp:0;Si:0;Di:0;Ds:0;Es:0;Flags:0);
-
- OurDseg: integer = 0; {Our Data Segment Value }
- OurSseg: integer = 0; {Our Stack Segment Value }
- DosSseg: integer = 0; {Dos Stack Segment Value }
- Inuse : Boolean = false; {Recursion flag }
- { The following two constants *MUST* remain in the Ip:CS order }
- { because StaySave uses them as a JMP target }
- User_IntIP : integer = 0; {Pointer to Original IP Int value }
- User_IntCs : integer = 0; {Pointer to Original Cs Int value }
- StackSize : integer = 0; {Current User/or Dos Stack word size}
-
- { - - - - - - - V A R I A B L E S - - - - - - - - - - - - - - - - - - - - - -}
- Var
- SaveRegs : regtype;
- HalfRegs : halfregtype absolute regs;
- Terminate_flag : boolean ;
- Keychr : char ;
- Old_Xpos,Old_Ypos : integer ;
-
-
- {-----------------------------------------------------------------------------}
- { W I N D O W R O U T I N E }
- {---------------------------------------------------------------------------- }
-
- {$I WINDO.INC}
-
- {-----------------------------------------------------------------------------}
- { S T A Y E X I T }
- {-----------------------------------------------------------------------------}
- {$I STAYXIT.320}
-
- {----------------------------------------------------------------------}
- { B e e p : S o u n d t h e H o r n }
- {----------------------------------------------------------------------}
- Procedure Beep(N :integer); {------------------------------------------}
- Begin { This routine sounds a tone of frequency }
- Sound(n); { N for approximately 100 ms }
- Delay(100); {------------------------------------------}
- Sound(n div 2);
- Delay(100);
- Nosound;
- End {Beep} ;
-
- {-----------------------------------------------------------------------------}
- { THE FOLLOWING ARE THE USER INCLUDE ROUTINES }
- {-----------------------------------------------------------------------------}
-
- {-----------------------------------------------------------------------------}
- { E P S O N P R I N T E R S E T U P }
- {-----------------------------------------------------------------------------}
- Procedure EP;
- {$I EP.INC}
-
- {-----------------------------------------------------------------------------}
- { S C R E E N C O U N T E R }
- {-----------------------------------------------------------------------------}
- Procedure SC;
- {$I SC.INC}
-
- {-----------------------------------------------------------------------------}
- { P R O G R A M A I D E }
- {-----------------------------------------------------------------------------}
- Procedure PgmAide;
- {$I PGM-AIDE.DVR}
-
- {-----------------------------------------------------------------------------}
- { THE ABOVE ARE THE USER INCLUDE ROUTINES }
- {-----------------------------------------------------------------------------}{---------------------------------------------
- {-----------------------------------------------------------------------------}
- { P R O C E S S I N T E R R U P T }
- { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
- Procedure Process_Intr;
-
- { PURPOSE: This procedure replaces the standard keyboard interrupt. If
- anything but <Alt>-F1 is pressed, the key is passed on to the
- standard keyboard interrupt. B*U*T when <Alt>- F1 is pressed,
- this program takes over. The variable InUse is set to TRUE to
- ensure that this code doesn't try to run "on top of itself " AND to
- indicate to the Inline code to save/restore the original interrupt
- regs.
- }
- Begin
- { K e y b o a r d Interrupt o c c u r s here }
- {----------------------------------------------------------------------}
- { This could also have the include data as $I StaySave.331 }
- {****************************************************************************}
- { S T A Y S A V E . I N C }
- { }
- { This is the Staysave.Inc file included above }
- { }
- { Separate the code out into a file or replace the $I Staysave.331 }
- { statement above with this code. }
- {****************************************************************************}
-
- {This Inline routine will save the regs and Stack for Stay resident programs.
- It restores DS and SS from the previously saved integer constants "OurDseg"
- and "OurSSeg". This is important since Dos is not re-entrant and any attempt
- to use Interrupt I/O services will clobber the very stack on which the
- Resident Turbo program just saved its regs. Thus, on the final return, you
- and Toto will end up somewhere other than Kansas and without your Ruby Reds.
- }
-
- { Arthor: Lane Ferris
- - The Hunter's Helper -
-
- Distributed to the Public Domain for use without profit.
- Original Version 5.15.85
- }
- { On entry the Stack will already contain: }
- { 1) Sp for Dos }
- { 2) Bp for Dos }
- { 3) Ip for Dos }
- { 4) Cs for Dos }
- { 5) Flags for Dos }
- Inline (
-
- { The following routine avoids the overhead of saving the DOS stack }
- { when the INT 16 function was not for a character request. This happens }
- { often (every four chars) as DOS checks on ^S/^Q/^C/Keypressed ad.nausea }
-
- $80/$FC/$00/ {Cmp Ah,00 If Char request, }
- $74/$07/ {Je ChrRqst enter Staysave code }
- $5D/$5D/ {Pop Bp/Pop Bp else Restore Bp & }
- $2E/ { Jump to Original Dos Interrupt }
- $FF/$2E/User_IntIP/ {Jmp Far Cs:[User_IntIp] }
-
- { Move the current active registers to a save place}
-
- {ChrRqst: }
- $FA / {Cli Stop all interrupts }
- { Bp and Sp aready saved at Begin Stmt }
- $55/ {Push Bp Save again for Regpak }
- $BD/Regs/ {Mov Bp,offset REGS address savearea}
- $2E/$89/$46/$00/ {CS:Mov [Bp+0],AX Save Users Registers }
- $2E/$89/$5E/$02/ {Cs:Mov [Bp+2],Bx}
- $2E/$89/$4E/$04/ {CS:Mov [Bp+4],CX}
- $2E/$89/$56/$06/ {CS:Mov [Bp+6],DX}
- $2E/$8F/$46/$08/ {Pop Cs:[Bp+8] Fetch Bp from stack }
- $2E/$89/$76/$0A/ {CS:Mov [Bp+A],SI}
- $2E/$89/$7E/$0C/ {CS:Mov [Bp+C],DI}
- $2E/$8C/$5E/$0E/ {CS:Mov [Bp+E],DS}
- $2E/$8C/$46/$10/ {CS:Mov [Bp+10],ES}
- $9C/ {PUSHF put Flags on stack to retrieve }
- $2E/$8F/$46/$12/ {POP Cs:[Bp+12]}
-
- { If Current SS := [OurSseg] or (Inuse = True), }
- { then dont overlay the previously saved stack. }
- { This program is being recursive. }
-
- $2E/$80/$3E/Inuse/$01/ {Cmp Cs:[Inuse],1 Inuse = True ? }
- $74/$62/ {Je ReCurin Yes, -J-U-M-P- }
-
- { Switch the SS:Sp reg pair over to ES:Si }
- { Put Turbo's Stack pointers into SS:Sp }
-
- $2E/$8C/$16/DosSSeg/ {Mov Cs:DosSSeg,SS Save Dos Stack Segment }
- $8C/$D6/ {Mov Si,SS Es gets Dos stack }
- $8E/$C6/ {Mov Es,Si }
- $2E/$8E/$16/OurSSeg/ {Mov SS,Cs:OurSSeg SS Gets our Stack segment }
- $2E/$8E/$1E/OurDseg/ {Mov Ds,Cs:Our_Ds DS Gets our Data Segment }
-
- { If ES:Si (stack ptr) <> OurSSeg then }
- { Sp := Virgin Turbo Stack pointer. }
- { If Es:Si := OurSSeg, then this is a Read or }
- { Write before Inuse was set True. Dont clobber }
- { the current setting of Turbo stack pointer. }
-
- $2E/$3B/$36/OurSSeg/ {Cmp Si,Cs:OurSSeg If SS := OurSSeg then }
- $89/$E6/ {Mov Si,Sp dont clobber saved regs }
- $74/$05/ {Je $+5 else get virgin stack ptr }
- $3E/$8B/$36/$74/$01/ {Mov Si,Ds:[174] ..(cf. code at B2B 3.0x) }
- $87/$F4/ {Xchg Sp,Si Set new Stack Pointer }
-
- { Stack Dos/User interrupted pgm regs for Exit. }
- { These are the original interrupt process regs }
- { that must be returned on interrupt return }
-
- $2E/$FF/$76/$00/ {Push [Bp+0] Save Ax }
- $2E/$FF/$76/$02/ {Push [Bp+2] Save Bx }
- $2E/$FF/$76/$04/ {Push [Bp+4] Save Cx }
- $2E/$FF/$76/$06/ {Push [Bp+6] Save Dx }
- {Push [Bp+8] Save Bp }
- $2E/$FF/$76/$0A/ {Push [Bp+A] Save Si }
- $2E/$FF/$76/$0C/ {Push [Bp+C] Save Di }
- $2E/$FF/$76/$0E/ {Push [Bp+E] Save Ds }
- $2E/$FF/$76/$10/ {Push [Bp+10] Save Es }
-
- { Now stack the lesser of current stack size or }
- { 40 Words to our stack, to be re-stack on the }
- { interrupted pgms stack on exit. This is done }
- { to allow recursive entry into Dos/or other non }
- { re-entrant pgms. }
-
- $29/$C9/ {Sub Cx,Cx Find minimum of current stack }
- $29/$F1/ {Sub Cx,Si size or 40 words to save. }
- $D1/$E9/ {Shr Cx,1 Stackbytes/2 for words. }
- $83/$F9/$40/ {Cmp Cx,+40 This keeps up from overrunning }
- $7E/$03/ {Jle $+3 the Stack Segment when it is less}
- $B9/$40/$00/ {Mov Cx,40 than Dos stack size }
- $2E/$89/$0E/StackSize/ {Mov Cs:StackSize,Cx Save current stack size }
- {Restack:}
- $26/$FF/$34/ {Push Es:[Si] Our Stack := Dos Es:Si }
- $46/$46/ {Inc Si/Inc Si Get Next Dos Stack Word }
- $E2/$F9/ {Loop to Restack }
-
- $56/ {Push Si Save bottom of Dos Stack }
- $2E/$8C/$5E/$0E/ {Mov Cs:[Bp+E],Ds Set New Data Segmt in regs}
- {Recurin} { Jump here if Recursion }
- $FB {Sti Enable Interrupts }
-
- ) ;
- {...........................................................................}
- {---------------------------------------------------------------------------}
- { END OF THE STAYSAVE REGISTER ROUTINE }
- {---------------------------------------------------------------------------}
-
- { Set New Data Segmt in regs}
- {----------------------------------------------------------------------}
- { Check the Int 16 request function in Ah reg:
- 0 = read character from Keyboard
- 1 = check character available
- 2 = check shift key values
- }
-
- { HalfRegs.Ah = 0 This is a Character Request because StaySave }
- { doesnt allow an enter here unless it is! }
-
- Intr (User_Int, Regs); { Use the DOS replaced interrupt}
- { Get Key from Keyboard }
- If (Halfregs.Ah = Our_Char) { Separate the tests so code }
- { performs efficiently. }
- then if (not InUse) then { Must be OUR key and not busy }
-
- Begin { PROGRAM AIDE }
- InUse := true; { "dont clobber saved stack"}
- {--------------------------------------------------------------------------}
- { INVOKE USER PROCEDURE HERE }
- {--------------------------------------------------------------------------}
- PgmAide;
- {--------------------------------------------------------------------------}
- { END USER PROCEDURE HERE }
- {--------------------------------------------------------------------------}
- Regs.Ax := $1D00; { Give Dummy Ctrl Scan Code to }
- { interrupted program }
- While (not Keypressed); { Get input key for the users }
- SaveRegs.Ax := 0 ; { interrupted program }
- Intr(User_Int,SaveRegs); { Get the Scancode }
- Regs.Ax := SaveRegs.Ax;
- If HalfRegs.Ah = Our_Char then Beep(650);
-
- InUse := false; { ok to restore interrupted stack }
- End; { PROGRAM AIDE }
- {---------------------------------------------------------------------------}
- {---------------------------------------------------------------------------}
- { BEGINNING OF THE STAYRSTR ROUTINE }
- {---------------------------------------------------------------------------}
- { This could also be used as $I StayRstr.331 }
- {****************************************************************************}
- { S T A Y R S T R . I N C }
- { }
- { This is the StayRstr.Inc file included above }
- { Separate the code out into a file or replace the $I StayRstr.331 }
- { statement above with this code. }
- {****************************************************************************}
- {Version 3.31}
- { Inline Code to restore the stack and regs moved}
- { to the Turbo Resident Stack which allows }
- { re-entrancy into Dos for I/O and recursion }
- { for Turbo Terminate & Stay Resident programs. }
-
- { Author: Lane Ferris }
- { - The Hunter's Helper - }
- { Distributed to the Public Domain for use without profit. }
- { Original Version 5.15.85 }
- {----------------------------------------------------------------------}
- { Restore the Dos (or interrupted pgm) Regs and Stack }
- {----------------------------------------------------------------------}
- { On entry the Stack will already contain: }
- { Pointer to bottom of stack }
- { Bottom of Dos Stack Ptr }
- { StackSize words of saved pgm stack }
- { Dos Flags }
- { Dos Code Segment }
- { Dos Instruction Ptr }
- { Dos Base Pointer }
- { Dos Original Stack Ptr }
-
-
- { Retrieve the Regpack registers as they were }
- { stored for the Interrupt Entry. }
-
- inline(
- $BD/Regs/ {Mov Bp,offset REGS}
- $2E/$8B/$46/$00/ {CS:Mov Ax,[Bp+0]}
- $2E/$8B/$5E/$02/ {Cs:Mov Bx,[Bp+2]}
- $2E/$8B/$4E/$04/ {CS:Mov Cx,[Bp+4]}
- $2E/$8B/$56/$06/ {CS:Mov Dx,[Bp+6]}
-
- $2E/$8B/$76/$0A/ {CS:Mov Si,[Bp+A]}
- $2E/$8B/$7E/$0C/ {CS:Mov Di,[Bp+C]}
- $2E/$8E/$5E/$0E/ {CS:Mov DS,[Bp+E]}
- $2E/$8E/$46/$10/ {CS:Mov ES,[Bp+10]}
- $2E/$FF/$76/$12/ {Push Cs:[Bp+12] }
- {PopF }
- { The following code was added to avoid }
- { the 80286 Pop flag (POPF) bug which }
- { enables interrupts while we are trying}
- { to POP the stack on odd byte boundry }
- $EB/$01/ {JMP $+3 Skip over IRET }
- $CF/ {IRET POP IP/CS/Flags }
- $0E/ {PUSH CS Make a return }
- $E8/$FB/$FF/ {CALL CS:$-2 Pop the Flags}
-
- { If [Cs:InUse]:= True, then dont restore the stack.}
- { This program is being recursive. Else restore Dos }
- { Stack and Program Entry registers for final exit. }
-
- $2E/$80/$3E/Inuse/$01/ {Cmp byte ptr Cs:[Inuse],1 }
- $74/$25/ {Je ReCurOut J-U-M-P }
-
- { Move "StackSize" words back to the interrupted pgms}
- { stack. The originals could have been clobber by our}
- { being recursive. (Especially true of DOS) }
-
- $FA / { Cli ; Stop all interrupts }
- $5E/ {Pop Si Bottom of Dos Stack }
- $2E/$8B/$0E/StackSize/ {Mov Cx,Cs:StackSize Saved Stack Words }
- $2E/$8E/$06/DosSSeg/ {Mov ES,Cs:DosSSeg Get Dos StackSegment }
- {Restack:}
- $4E/$4E/ {Dec Si/Dec Si Backup Dos Stack }
- $26/$8F/$04/ {Pop Es:[Si] Dos Stack := Our Stack }
- $E2/$F9/ {Loop to Restack }
- $89/$F5/ {Mov Bp,Si Save Dos Sp across Pops }
-
- { - C - A - U - T - I - O - N - }
- { Restore the original interrupted programs regs }
- { except Ax. Ax usually contains status. It contains }
- { a scan code and key for Int 16. You may want to }
- { rework this if using another interrupt. }
-
- $07/ {Pop Es }
- $1F/ {Pop Ds }
- $5F/ {Pop Di }
- $5E/ {Pop Si }
- $5A/ {Pop Dx }
- $59/ {Pop Cx }
- $5B/ {Pop Bx }
- $44/$44/ {Inc sp/Inc sp Thow old Ax value away }
-
- $89/$EC/ {Mov Sp,Bp Setup Dos Stack Ptr }
- $2E/$8E/$16/DosSSeg/ {Mov SS,Cs:DosSSeg Give back Dos Stack }
-
- {RecurOut} {Clean up the Stack }
- $5D/ {Pop Bp Throw away old dos Sp }
- $BD/Regs/ {Mov Bp,offset REGS }
- $2E/$FF/$76/$12/ {Push Cs:[Bp+12] Flags from last }
- {PopF interrupt. }
- { The following code was added to avoid }
- { the 80286 Pop flag (POPF) bug which }
- { enables interrupts while we are trying }
- { to POP the stack on odd byte boundry }
-
- $EB/$01/ {JMP $+3 Skip over IRET }
- $CF/ {IRET POP IP/CS/Flags }
- $0E/ {PUSH CS Make a return }
- $E8/$FB/$FF/ {CALL CS:$-2 Pop the Flags}
-
- $5D/ {Pop Bp Retrieve old BP }
- $FB/ {Sti Enable interrupts }
- $CA/$02/$00 {Ret Far 002 Thow old flags away}
- );
- {.......................................................................}
- {---------------------------------------------------------------------------}
- { END OF THE STAYRSTR ROUTINE }
- {---------------------------------------------------------------------------}
-
- End ;{Process_Intr}
- {-----------------------------------------------------------------------}
-
- {-------------------------------------------------------------------------}
- { M A I N }
- {-------------------------------------------------------------------------}
- { The main program installs the new interrupt routine }
- { and makes it permanently resident as the keyboard }
- { interrupt. The old keyboard interrupt is addressed }
- { through #60H, so it can still be used. }
- { }
- { The following dos calls are used: }
- { Function 25 - Install interrupt address }
- { input al = int number, }
- { ds:dx = address to install }
- { Function 35 - get interrupt address }
- { input al = int number }
- { output es:bx = address in interrupt }
- { Function 31 - terminate and stay resident }
- { input dx = size of resident program }
- { obtained from the memory }
- { allocation block at [Cs:0 - $10 + 3] }
- { Function 49 - Free Allocated Memory }
- { input Es = Block Segment to free }
- { Interrupt 20 - Return to invoking process }
- {-----------------------------------------------------}
-
- {-----------M A I N B L O C K---------------------------------------------}
- Begin {**main**}
-
- InUse := false;
- OurDseg:= Dseg; { Save the Data Segment Address for Interrupts }
- OurSseg:= Sseg; { Save our Stack Segment for Interrupts }
-
-
- Terminate_Flag := false ;
- SaveRegs.Es := 00; { clear for Dos 3.0 bug }
- {now install the interrupt routine}
-
- SaveRegs.Ax := $3500 + User_Int;
- Intr($21,SaveRegs); {Check to make sure int not already used}
-
- if SaveRegs.Es <> $00 then
- WriteLn ('Interrupt in use -- can''t install Resident Turbo Code')
- else
- begin
-
-
- SaveRegs.Ax := $3500 + Kybrd_Int;
- Intr($21,SaveRegs); {get the address of keyboard interrupt }
-
- SaveRegs.Ax := $2500 + User_Int;
- SaveRegs.Ds := SaveRegs.Es;
- SaveRegs.Dx := SaveRegs.Bx;
- Intr($21,SaveRegs); { set the user-interrupt address to point
- { to the keyboard interrupt address }
-
- SaveRegs.Ax := $2500 + Kybrd_Int;
- SaveRegs.Ds := Cseg;
- SaveRegs.Dx := Ofs(Process_Intr);
- Intr ($21,SaveRegs); { set the keyboard interrupt to point to
- "Process-Intr" above}
-
- User_IntIp := MemW[0:User_Int * 4 ]; { Location of User Interrupt Ip }
- User_IntCs := MemW[0:User_Int * 4 +2];{ Location of User Interrupt Cs }
-
- {----------------------------------------------------------------------------}
- { INITIALIZE YOUR PROGRAM HERE }
- {----------------------------------------------------------------------------}
- { Initialize Your Progam Here since you wont get control again
- until "Our_Char" is entered from the Keyboard. }
- Writeln(' Turbo Stay-Resident Program Aide');
- Writeln(' Press Alt-F1 to Call');
-
- {----------------------------------------------------------------------------}
- { END OF INITALIZE PROGRAM CODE }
- {----------------------------------------------------------------------------}
-
- {now terminate and stay resident}
- { Pass return code of zero }
- SaveRegs.Ax := $3100 + 0 ; { Terminate and Stay Resident }
- SaveRegs.Dx := MemW [Cseg-1:0003] ; { Prog_Size from Allocation Blk}
- Intr ($21,SaveRegs);
-
- end;
- { END OF RESIDENCY CODE }
- end.