home *** CD-ROM | disk | FTP | other *** search
- /*-----------------------------------------------------------------------*
- * filename - setjmp.cas
- *
- * function(s)
- * setjmp - nonlocal goto
- * longjmp - performs a nonlocal goto
- *-----------------------------------------------------------------------*/
-
- /*
- * C/C++ Run Time Library - Version 5.0
- *
- * Copyright (c) 1987, 1992 by Borland International
- * All Rights Reserved.
- *
- */
-
-
- #pragma inline
- #include <asmrules.h>
- #include <setjmp.h>
-
- #ifdef __BOSS__
- #include <int2f.h>
-
- extern unsigned char _protected;
-
- /*
- []---------------------------------------------[]
- | ModifyCStoID |
- |---------------------------------------------|
- | segment -> ID |
- | |
- []---------------------------------------------[]
- */
-
- int ModifyCStoID(int segment){
-
- asm push bx
- asm push cx
- asm push dx
- asm push ds
- asm push es
- asm push di
- asm push si
- asm mov ax, DGROUP
- asm mov ds, ax
- asm cmp byte ptr DGROUP:_protected,0
- asm jnz sameexit
- asm mov cx, segment
- asm mov bx, BOSS_ConvertSelectorToSegmentHandle
- asm mov ax, 0x0FB42
- asm int 0x02F
- asm cmp dx, STSUCCESS
- asm je modseg
-
- sameexit:
- asm mov ax, segment
- asm jmp exit
-
- modseg:
-
- asm mov es, cx
- asm test word ptr es:[bx].mpb_flags, NSMOVE
- asm jz sameexit
- asm shr bx, 1
- asm shr bx, 1
- asm shr bx, 1
- asm shr bx, 1
- asm add cx, bx
- asm mov ax, cx
-
- exit:
-
- asm pop si
- asm pop di
- asm pop es
- asm pop ds
- asm pop dx
- asm pop cx
- asm pop bx
- return(_AX);
- }
-
- /*
- ;[]---------------------------------------------[]
- ; | ModifyIDtoCS |
- ; |---------------------------------------------|
- ; | CX->CX |
- ; | |
- ;[]---------------------------------------------[]
- */
-
- int ModifyIDtoCS(int ID){
-
-
- asm push bx
- asm push cx
- asm push dx
- asm push ds
- asm push es
- asm push di
- asm push si
- asm mov ax, DGROUP
- asm mov ds, ax
- asm cmp byte ptr DGROUP:_protected,0
- asm jz real
- asm mov ax, ID
- asm jmp exit
-
- real:
-
- asm mov cx, ID
- asm mov bx, BOSS_LocateMoveableSegment
- asm mov ax, 0x0FB42
- asm int 0x2F
- asm mov ax, cx
-
- exit:
-
- asm pop si
- asm pop di
- asm pop es
- asm pop ds
- asm pop dx
- asm pop cx
- asm pop bx
-
- return(_AX);
-
- }
-
- #endif // __BOSS__
-
- /* leaves current FPU stack pointer in a word at SS:bx */
- /* preserves all registers but bx, cx */
-
- /*-----------------------------------------------------------------------*
-
- Name setjmp - nonlocal goto
-
- Usage #include <setjmp.h>
- int setjmp(jmp_buf jmpb);
-
- Prototype in setjmp.h
-
- Description Saves current context information (register, stack
- position, and segment values) in the jmp_buf structure and
- then returns to the caller.
-
- Setjmp returns 0 when called directly. The caller of setjmp
- may be "returned to" again by longjmp, when the function
- result will never be zero.
-
- The jmp_buf contains the entire context necessary for a C
- task, including all segments and the complete flag word.
- Only the AX,BX,CX,DX,ES registers are lost, but then the
- caller of setjmp does not expect them to be preserved
- through a function call.
-
- On entry, the stack frame looks like:
-
- top old BP
- DI
- SI
- #if defined (__HUGE__)
- DS
- #endif
- IP
- #if (LPROG)
- CS
- #endif
- jmpb OFFSET
- #if (LDATA)
- jmpb SEGMENT
- #endif
-
- Return value setjmp returns 0 when it is initially called.
-
- *------------------------------------------------------------------------*/
- int _CType setjmp(jmp_buf jmpb)
- {
- asm pushf
- asm pop bx /* save flags in bx */
-
- asm mov dx, es /* save es */
-
- asm mov cx, di /* save di */
-
- #if LDATA
- asm LES di, jmpb
- #else
- asm mov di, jmpb
- asm push DS
- asm pop ES
- #endif
-
- asm cld
- asm lea ax, jmpb
-
- #if defined(__PAS__)
- #if LPROG
- asm add ax,4
- #else
- asm inc ax
- asm inc ax
- #endif
- #endif
-
- asm stosw /* sp */
- asm mov ax, SS
- asm stosw /* SS */
-
- /* Save the Floating Point Unit */
- #ifdef __DEEP_STACK__
- #if defined(__MEDIUM__) || defined(__LARGE__) || defined(__HUGE__)
- asm push ds
- asm mov ax,_EMUSEG
- asm mov ds,ax
- asm call dword ptr ds:[0]
- asm pop ds
- #else
- asm push cs /* simulate far call */
- asm call ds:[___fpustate]
- asm mov ax, SS:[bx]
- asm stosw /* FPU */
- #endif
- #else
- asm xchg ax,bx
- asm stosw /* flags */
- #endif
-
- #if LPROG
- asm mov ax, W1(jmpb-cPtrSize) /* large code */
- #else
- asm mov ax, CS
- #endif
-
- #ifdef __BOSS__
- asm push ax
- asm call _ModifyCStoID
- asm add sp, 2
- #endif
-
- asm stosw /* CS */
- asm mov ax, W0(jmpb-cPtrSize)
- asm stosw /* IP */
-
- asm mov ax, [bp]
- asm stosw /* BP */
- asm xchg ax, cx
- asm stosw /* DI */
- asm mov ax, dx
- asm stosw /* ES */
- asm xchg ax, si
- asm stosw /* SI */
-
- #if defined(__HUGE__)
- asm pop ax
- asm push ax /* caller's DS */
- #else
- asm mov ax, ds
- #endif
-
- asm stosw /* DS */
- asm mov es, dx /* restore ES */
- return 0;
- }
-
-
- /*-----------------------------------------------------------------------*
-
- Name longjmp - performs a nonlocal goto
-
- Usage #include <setjmp.h>
- void longjmp(jmp_buf jmpb, int retval);
-
- Prototype in setjmp.h
-
- Description Restores context information (register, stack position, and
- segment values) from the jmp_buf structure, which must
- previously have been saved there by setjmp, and then
- returns to the original caller of setjmp with val as the
- return value as if returning from setjmp. The difference
- between a setjmp return and a longjmp is that setjmp
- returns zero, longjmp returns "val". Val can never be zero:
- if zero argument is supplied, 1 is substituted.
-
- Longjmp never returns to its own caller. If the contents of
- jmpb are not set, or if the context therein is for a
- function which is not now active (if it has finished and
- returned) then the result will generally be to crash the
- program. The safest styles of use of the setjmp/longjmp
- pair are to effect a return upward through several nested
- procedure layers to a parent procedure designed to handle
- exceptions, or to place both setjmp and longjmp within a
- single scheduler/event handler lexical block.
-
- Return value longjmp cannot return the value 0; if passed 0 in val,
- longjmp will return 1.
-
- *------------------------------------------------------------------------*/
- void _CType longjmp(jmp_buf jmpb, int retval)
- {
- /* sneaky way to do if (retval==0) retval=1; */
- asm mov dx, retval
- asm cmp dx, 1 /* generates carry if dx=0 */
- asm adc dx, 0 /* if was 0, now it's 1 */
- asm LDS_ si, jmpb
- asm cld
-
- /* Change context begins with changing stack */
- #ifdef __BOSS__
- asm push dx
- asm mov ax, 0xfb42
- asm mov bx, BOSS_FreezeUnfreezeStack
- asm mov cx, FREEZE_SP
- asm int 2fh
- asm pop dx
- #endif
-
- asm pushf /* save state of interrupt flag */
- asm pop bx /* in bx */
- asm lodsw /* sp */
- asm cli
- asm mov ss, [si] /* SS */
- asm mov sp, ax
- asm push bx /* restore state of interrupt flag */
- asm popf
- asm lodsw /* skip SS */
-
- /* Restore the Floating Point Unit */
- #ifdef __DEEP_STACK__
- #if defined(__MEDIUM__) || defined(__LARGE__) || defined(__HUGE__)
- asm push ds
- asm mov ax,_EMUSEG
- asm mov ds,ax
- asm call dword ptr ds:[0]
- asm pop ds
- #else
- asm push cs /* simulate far call */
- asm call ds:[___fpustate]
- asm lodsw /* FPU */
- asm mov SS:[bx], ax
- #endif
- #else
- asm lodsw /* flags */
- #endif
-
- /* Build the return-link to the caller of setjmp */
- asm push ax /* flags */
- asm lodsw /* CS */
- asm push ax
- asm lodsw /* IP */
- asm push ax
-
- /* Restore other working registers */
- asm lodsw /* BP */
- asm xchg bp, ax
- asm lodsw /* DI */
- asm xchg di, ax
- asm lodsw /* ES */
- asm mov es, ax
- asm lodsw /* SI */
- asm mov ds, [si]
- asm xchg si, ax
-
- #ifdef __BOSS__
- asm push dx
- asm mov ax, 0xfb42
- asm mov bx, BOSS_FreezeUnfreezeStack
- asm mov cx, UNFREEZE_SP
- asm int 2fh
- asm pop dx
-
- asm pop bx /* IP CS on stack!! */
- asm call _ModifyIDtoCS
- asm add sp, 2
- asm push ax /* CS */
- asm push bx /* IP */
- #endif
-
- asm xchg ax, dx /* put result in ax */
- asm iret /* return to original caller of setjmp */
- }
-