petera@hcrvax.UUCP (Smith) (01/24/86)
Here is a source file for some useful Lattice C routines for MS-DOS. These are for the Lattice C 'L' or large memory model. They include 3 very useful functions. setjmp(), longjmp(), and _envget(). The setjmp() and longjmp() require a header file with a declaration for the type 'jmpbuf' this should be a 10 integer array. You should assemble it with MASM and make sure that the file LM8086 is present, this is provided with the compiler. Note that _envget() can be used to implement the getenv() call with a little bit of 'C'. I am now using these routines in a Lisp interpreter where setjmp() and longjmp() get lots of exercise to say the least! Look for the Lisp interpreter uuencoded executable Real Soon Now! Oh, these are for Lattice version 2.03 and I do not know if they will work with later/earlier versions but I would be surprised if they did not. Peter Ashwood-Smith, Human Computing Resources and University of Toronto. Ontario, Canada. (416) 593-7574. ========CUT HERE============================================== PAGE 60,132 TITLE ROUTINES for use by the MSDOS Lisp interpreter SUBTTL Peter Ashwood-Smith for TANDY 2000 1985. NAME LONGJMP PAGE INCLUDE LM8086.MAC PAGE ; TEMPORARY STORAGE AND EQUATES ; ============================= POFFS EQU 6 ; offset for lattice C L model. PAGE PSEG ; ; SYNOPSIS: longjmp(longlabel,value) ; jmp_buf longlabel; ; int value; ; ; longjmp will restore the SP and SS segments from ; the longlabel buffer and return. This has the ; effect of skipping a whole pile of returns. Have ; a look at the Unix manuals if you do not know what ; these functions do. ; ; ; PUBLIC LONGJMP LONGJMP PROC FAR PUSH BP MOV BP,SP MOV AX,[BP+POFFS+2] ; AX = high bits of ptr MOV ES,AX ; ES = high bits MOV DI,[BP+POFFS] ; DI = low bits of ptr MOV SP,ES:[DI] ; SP = *ptr MOV AX,ES:[DI+2] MOV SS,AX MOV BP,SP MOV AX,ES:[DI+4] ; AX = SETJMP return addr MOV [BP+2],AX ; put return addr in STACK MOV AX,ES:[DI+6] MOV [BP+4],AX MOV AX,ES:[DI+8] ; SETJMP's BP value MOV [BP],AX ; put into stack for restore MOV AX,ES:[DI+10] ; restore the DS value MOV DS,AX ; MOV AX,ES:[DI+12] ; restore the ES value MOV ES,AX MOV AX,1H ; load AX with user return POP BP ; pop the SETJMP's BP push RET ; do the SETJMP's ret LONGJMP ENDP PAGE ; SYNOPSIS: setjmp(longlabel) ; jmp_buf longlabel; ; int value; ; ; Setjmp will save the stack pointer, and other critical ; registers in the buffer provided so that longjmp ; can restore them to perform the long jump operation. ; the jmp_buf must be more than 10 integers wide. ; ; PUBLIC SETJMP SETJMP PROC FAR PUSH BP MOV BP,SP MOV AX,ES ; save ES for later. MOV CX,AX ; in CX MOV AX,[BP+POFFS+2] ; load the pointer to buff MOV ES,AX ; es high part of pointer MOV DI,[BP+POFFS] ; di low part of pointer MOV ES:[DI],SP ; put sp in buf[0] MOV AX,SS ; get stack segment 'ss' MOV ES:[DI+2],AX ; put ss in buf[1] MOV AX,[BP+2] ; get setjmp return addr MOV ES:[DI+4],AX ; put return addr in buf[2] MOV AX,[BP+4] ; and buf[3] for long model MOV ES:[DI+6],AX MOV AX,[BP] ; get setjmp pop bp value MOV ES:[DI+8],AX ; put in buf[3] MOV AX,DS MOV ES:[DI+10],AX ; put away DS MOV ES:[DI+12],CX ; put away ES XOR AX,AX ; return 0 always POP BP RET SETJMP ENDP PAGE ; ; SYNOPSIS: char _envget(i) ; int i; ; ; EFFECT : Get the ith byte from the environment area. ; used by the function 'getenv'. ; PUBLIC _ENVGET ; _ENVGET(I:INTEGER) EXTRN _PSP:DWORD _ENVGET PROC FAR PUSH BP MOV BP,SP PUSH DS MOV DI,[BP+POFFS] ; load offset parameter 'i' MOV AX,_PSP+2 ; AX = segment address of PSP MOV DS,AX ; DS = &PSP MOV AX,DS:[2CH] ; AX = PSP[2CH] (env seg ptr) MOV DS,AX ; DS = env seg ptr MOV AL,DS:[DI] ; AL = ENV[i] XOR AH,AH POP DS POP BP RET _ENVGET ENDP ENDPS END