home *** CD-ROM | disk | FTP | other *** search
- {****************************************************************************}
- { S T A Y S A V E . I N C }
- {****************************************************************************}
-
- {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.
- }
- { author: Copyright (C) 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 }
-
- $9C/ {PushF Save Flags }
- $80/$FC/$00/ {Cmp Ah,00 If Char request, }
- $75/$17/ {Jne Skipit Not for us. }
- $2E/
- $FF/$1E/Dos_Intip/ {Call Far Cs:[Original$16] }
- $9C/ {PushF Save Return Flags }
- $80/$FC/Our_Char/ {Cmp Ah,Cs:OurChar Our Key? }
- $74/$1A/ {Je GotIt enter Staysave code }
- {POPF Restore Int 16 flags }
- $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/$5D/ {Pop BP/PopBP Restore BP }
- $CA/$02/$00/ {RetF 2 Return w/Key discard flags }
-
- {Skipit} {Jmp to Original Dos Intr $16 }
- {PopF Restore the Flags }
- $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/$5D/ {Pop Bp/Pop Bp else Restore Bp & }
- $2E/ { Jump to Original Dos Interrupt }
- $FF/$2E/Dos_IntIP/ {Jmp Far Cs:[DOS_IntIp] }
-
- { Move the current active registers to a safe place}
- {GotIt}
- {Pop Saved Flags}
- $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}
- $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 returned 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 us 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 }
-
- ) ;
- {...........................................................................}