home *** CD-ROM | disk | FTP | other *** search
-
- {
- With this unit, it doesn't matter if the overlay is separate,
- or tacked onto the end of the .EXE file -- the program will
- run either way.
-
- As written, this unit also uses OVERXMS, a PD unit written
- Wilbert Van Leijen. Floating around the BBS's as OVERXMS.ZIP
- You may delete the references to XMS.
- The XMS stuff is in there because the program I copied this
- code from will run on a 486 and just about all of the college
- machines have XMS memory -- few if any have EMS. }
-
- {$A-,B+,D-,F+,I-,L-,N-,O-,Q+,R-,S-,V-}
-
- UNIT RVOVRLAY;
-
- { This unit starts the overlay manager }
-
- INTERFACE
- Const
- ovrNoXMSDriver = -7; { No XMS driver installed }
- ovrNoXMSMemory = -8; { Insufficient XMS memory available }
-
-
- IMPLEMENTATION
-
- USES DOS, OVERLAY;
-
- { OVERXMS - Loads overlays in XMS.
- Assembly-language portion written by Wilbert van Leijen }
- Procedure OvrInitXMS; External;
- {$L OVERXMS.OBJ }
-
- Function Exist(Filename:string):boolean;
- {returns true if file exists}
-
- var Inf: SearchRec;
-
- begin
- FindFirst(Filename,AnyFile,Inf);
- Exist := (DOSError = 0);
- end; {Func Exist}
-
-
- Procedure S_Write (Msg : string);
-
- BEGIN {Dirty trick to generate less code}
- Write (msg);
- END;
-
-
- Procedure WriteOvrErrMsg;
-
- VAR
- garbage:char;
-
- BEGIN
- WRITE ('Overlay error: ',OvrResult,' ');
- IF (OvrResult = ovrOk) THEN S_WRITE ('Ok - No error');
- IF (OvrResult = ovrError) THEN S_WRITE ('Missing Overlay error');
- IF (OvrResult = ovrNotFound) THEN S_WRITE ('Overlay file not found');
- IF (OvrResult = ovrNoMemory) THEN S_WRITE ('No Memory for overlays');
- IF (OvrResult = ovrIOError) THEN S_WRITE ('Overlay IO Error');
- IF (OvrResult = ovrNoEMSDriver) THEN S_WRITE ('No EMS Driver');
- IF (OvrResult = ovrNoEMSMemory) THEN S_WRITE ('No EMS Memory');
- IF (OvrResult = ovrNoXMSDriver) THEN S_WRITE ('No XMS Driver');
- IF (OvrResult = ovrNoXMSMemory) THEN S_WRITE ('No XMS Memory');
- S_WRITE (^M^J);
- read (garbage);
- If OvrResult <> OvrOK THEN HALT (98);
- END; { Procedure WriteOvrErrMsg }
-
-
- BEGIN { main }
-
- IF (lo(DosVersion) < 3) THEN
- BEGIN
- WriteLn ('You are using DOS version ',Lo(DosVersion),
- '.',Hi(DosVersion));
- Writeln ('Mulesoft Revenge requires DOS v3.0 or greater.');
- HALT (99);
- END;
-
- { Start overlay manager and assume that overlay is in
- the .EXE file. If not found in .EXE file, assume the
- overlay file is separate from the .EXE file. }
-
- OVRINIT (paramstr(0));
-
- If (OvrResult = ovrError) THEN { Overlay not at end of .EXE file }
- OVRINIT (copy(paramstr(0), 1, Length(paramstr(0))-3) + 'OVR');
- IF (OvrResult <> OvrOk) THEN
- WriteOvrErrMsg
- ELSE { Try to load the overlay into XMS memory }
- BEGIN
- OvrInitXms;
- IF (OvrResult <> OvrOk) THEN
- OvrInitEms;
- END;
- END.
-
- {------------------------- snip, snip ----------------------------}
-
- Here is the .OBJ file that goes with this file ...
- you will need XX3402 o decode this output:
-
- Cut this out to a file named OVERXMS.XX.
- Execute XX3402 d OVERXMS.XX
-
- You will then get the file OVERXMS.OBJ to compile this unit
-
- *XX3402-000913-020294--72--85-48736-----OVERXMS.OBJ--1-OF--1
- U+o+0qxqNL7sPLAiEJBBFMUU++++53FpQa7j623nQqJhMalZQW+UJaJmQqZjPW+n9X8NW-A+
- ECafC26Q0qxqNL7sPLAiEJBBnMU1+21dH7M0++-cW+A+E84IZUM+-2F-J234a+Q+G-c++U2-
- ytM4++F1HoF3FNU5+0Wi+EA-+MKAJ++7I373FYZMIoJ5++V3K2ZII37DEk+7HpNGIYJHJIlI
- ++hDJZ71HoF3H2ZHJ++AHpNGF2xHG23CF2l3++dDJZ76FI3EHp75++dDJZ7GFI32EZJ4+0OE
- 2E+++UdDJZ77HYZIK2pHCE2+xcU2+20W+N4UgU20++093VU+h+fz5U++l+M2+8A++6k4+U19
- Aw+nocgS+++15U++UwAEXgAa+kM6+6DG+0O95Us+0xhptfg+-DTnYY8o0TwS+++9k5E2WFMM
- +ABJWymCFUMacEU+ckU+Aw0X0U0V4+0X1++acFM+cks+7e2M+8AE+1D+cl6+clE+7e2E+8AK
- +9E9jUU+zls+++j+R+F6ukGEiDnzLQc0+0O93UU+xw6-+5E4EWPz-UU+WFM6+1D+ckc+ckk+
- cks+cE++cl++cFU+cl6+WHsI+6YS3U0o0vs6+DwS+++1ycDH++j+R+9skzb1JMjgcE++AwY1
- -U++-F++Xg-EEGOV1U+9k5LhAxgnzkRFcE++7eAE+0O75VU+7cYy3U-HJkM4zls+++RTKmP5
- -V++++1rq566u4jzQUBNsgy9tJr1Aw+v-U++REF6uqOEi+-1nGwwU5E4iDbzupSEi--1nGy7
- 5U++X+M0+CWmzbI4iDXzunyEu5PzQl093VU+h+fz5U++iDnzumeEWls++9EynG55-U++HU0A
- 1U6+l+M++8A2+6k4-U15-U++++0A1U6+Aw0X++19RdnW+AE0J+5203E-l+lI+QED-U20l-A4
- +E925+M--AEU-U2-l2BI+QF9J+52KJE-l3tI+QFVJ+52N3E-l4hI+QFmJ+52RpE-l5dI+QG-
- J+52VZE-l6dI+QGiJ+52gpE-l9NI+QGtJ+52j+M--gGzJ+52kZE-lAJI+QH7J+52nJE-lB7I
- +QHKJ+52uEM--AHj-U2-lEQ4+EP35EM--wIx-U23lJhI+QJTJ+53QpE-lLZI+QK1-U23lMg4
- +ET3XJE0lN24+ET3ZEM-+gKMJ+53b3E-lO+4+E93cZE0lOM4+E93ekM-+z88+U++R+++
- ***** END OF BLOCK 1 *****
-
- {--------------------- OVERXMS.ASM --------------------- }
- { NEED MASM,TASM to compile }
-
- TITLE Turbo Pascal XMS support for loading overlays - By Wilbert van Leijen
- PAGE 65, 132
- LOCALS @@
-
- Data SEGMENT Word Public
- ASSUME DS:Data
-
- ; XMS block move record
-
- XmsMoveType STRUC
- BlkSize DD ?
- SrcHandle DW ?
- SrcOffset DD ?
- DestHandle DW ?
- DestOffset DD ?
- XmsMoveType ENDS
-
- ; TP overlay manager record
-
- OvrHeader STRUC
- ReturnAddr DD ? ; Virtual return address
- FileOfs DD ? ; Offset into overlay file
- CodeSize DW ? ; Size of overlay
- FixupSize DW ? ; Size of fixup table
- EntryPts DW ? ; Number of procedures
- CodeListNext DW ? ; Segment of next overlay
- LoadSeg DW ? ; Start segment in memory
- Reprieved DW ? ; Loaded in memory flag
- LoadListNext DW ? ; Segment of next in load list
- XmsOffset DD ? ; Offset into allocated XMS block
- UserData DW 3 DUP(?)
- OvrHeader ENDS
-
- XmsDriver DD ? ; Entry point of XMS driver
- ExitSave DD ? ; Pointer to previous exit proc
- XmsMove XmsMoveType <>
- OvrXmsHandle DW ? ; Returned by XMS driver
-
- Extrn PrefixSeg : Word
- Extrn ExitProc : DWord
- Extrn OvrResult : Word
- Extrn OvrCodeList : Word
- Extrn OvrDosHandle : Word
- Extrn OvrHeapOrg : Word
- Extrn OvrReadBuf : DWord
- Data ENDS
-
- Code SEGMENT Byte Public
- ASSUME CS:Code
- Public OvrInitXMS
-
- ovrIOError EQU -4
- ovrNoXMSDriver EQU -7
- ovrNoXMSMemory EQU -8
-
- OvrXmsExit PROC
-
- ; Release handle and XMS memory
-
- MOV DX, [OvrXmsHandle]
- MOV AH, 10
- CALL [XmsDriver]
-
- ; Restore pointer to previous exit procedure
-
- LES AX, [ExitSave]
- MOV Word Ptr [ExitProc], AX
- MOV Word Ptr [ExitProc+2], ES
- RETF
- OvrXmsExit ENDP
-
- AllocateXms PROC
-
- ; Determine the size of the XMS block to allocate:
- ; Walk the CodeListNext chain
- ; Store the total codesize in DX:AX
-
- XOR AX, AX
- XOR DX, DX
- MOV BX, [OvrCodeList]
- @@1: ADD BX, [PrefixSeg]
- ADD BX, 10h
- MOV ES, BX
- ADD AX, ES:[OvrHeader.CodeSize]
- ADC DX, 0
- MOV BX, ES:[OvrHeader.CodeListNext]
- OR BX, BX
- JNZ @@1
-
- ; Obtain number of kilobytes to allocate
-
- MOV BX, 1024
- DIV BX
- XCHG DX, AX
- INC DX
-
- ; Allocate the block
-
- MOV AH, 9
- CALL [XmsDriver]
- OR AX, AX
- JZ @@2
- MOV [OvrXmsHandle], DX
- @@2: RETN
- AllocateXms ENDP
-
- ; Function XmsReadFunc(OvrSeg : Word) : Integer; Far;
-
- XmsReadFunc PROC
-
- ; Swap the code from XMS to the heap
-
- PUSH BP
- MOV BP, SP
- MOV ES, [BP+6]
- MOV AX, ES:[OvrHeader.CodeSize]
- MOV Word Ptr [XmsMove.BlkSize], AX
- XOR AX, AX
- MOV Word Ptr [XmsMove.BlkSize+2], AX
- MOV AX, [OvrXmsHandle]
- MOV [XmsMove.SrcHandle], AX
- MOV AX, Word Ptr ES:[OvrHeader.XmsOffset]
- MOV Word Ptr [XmsMove.SrcOffset], AX
- MOV AX, Word Ptr ES:[OvrHeader.XmsOffset+2]
- MOV Word Ptr [XmsMove.SrcOffset+2], AX
- XOR AX, AX
- MOV [XmsMove.DestHandle], AX
- MOV Word Ptr [XmsMove.DestOffset], AX
- MOV AX, ES:[OvrHeader.LoadSeg]
- MOV Word Ptr [XmsMove.DestOffset+2], AX
- MOV AH, 11
- LEA SI, XmsMove
- CALL [XmsDriver]
- OR AX, AX
- JZ @@1
- DEC AX
- JMP @@2
-
- @@1: MOV AX, ovrIOError
- @@2: POP BP
- RETF 2
- XmsReadFunc ENDP
-
- ; Copy an overlaid unit from the heap to XMS
- ; If successful, carry flag is cleared
- ; In/Out:
- ; BX:DI = offset into XMS memory block
-
- CopyUnitToXms PROC
-
- ; XMS requires that an even number of bytes is moved
-
- MOV DX, ES:[OvrHeader.CodeSize]
- TEST DX, 1
- JZ @@1
- INC DX
- INC ES:[OvrHeader.CodeSize]
-
- ; Get the fields of the XMS block move structure
-
- @@1: MOV Word Ptr [XmsMove.BlkSize], DX
- XOR AX, AX
- MOV Word Ptr [XmsMove.BlkSize+2], AX
- MOV [XmsMove.SrcHandle], AX
- MOV Word Ptr [XmsMove.SrcOffset], AX
- MOV AX, [OvrHeapOrg]
- MOV Word Ptr [XmsMove.SrcOffset+2], AX
- MOV AX, [OvrXmsHandle]
- MOV [XmsMove.DestHandle], AX
- MOV Word Ptr [XmsMove.DestOffset], DI
- MOV Word Ptr [XmsMove.DestOffset+2], BX
- MOV AH, 11
- LEA SI, XmsMove
- CALL [XmsDriver]
-
- ; Bump code size
-
- ADD DI, DX
- ADC BX, 0
-
- ; Check return code from XMS driver
-
- OR AX, AX
- JZ @@2
- CLC
- RETN
-
- @@2: STC
- RETN
- CopyUnitToXms ENDP
-
- OvrXmsLoad PROC
- PUSH BP
- MOV BP, SP
-
- ; Walk the CodeList chain
- ; First segment is PrefixSeg+10h+OvrCodeList
- ; Push each element of overlaid unit list on the stack
- ; Keep the size of the linked list in CX
-
- MOV AX, [OvrCodeList]
- XOR CX, CX
- @@1: ADD AX, [PrefixSeg]
- ADD AX, 10h
- MOV ES, AX
- PUSH AX
- INC CX
- MOV AX, ES:[OvrHeader.CodeListNext]
- OR AX, AX
- JNZ @@1
-
- ; Loop:
- ; Pop each element of the overlaid unit list from the stack
-
- XOR BX, BX
- XOR DI, DI
- @@2: POP ES
- PUSH CX
- MOV AX, [OvrHeapOrg]
- MOV ES:[OvrHeader.LoadSeg], AX
- MOV Word Ptr ES:[OvrHeader.XmsOffset+2], BX
- MOV Word Ptr ES:[OvrHeader.XmsOffset], DI
-
- ; Load overlay from disk
-
- PUSH BX
- PUSH DI
- PUSH ES
- PUSH ES
- CALL [OvrReadBuf]
- POP ES
- POP DI
- POP BX
-
- ; Flag unit as 'unloaded'; check return code
-
- MOV ES:[OvrHeader.LoadSeg], 0
- NEG AX
- JC @@3
-
- CALL CopyUnitToXms
- JC @@3
-
- POP CX
- LOOP @@2
-
- @@3: MOV SP, BP
- POP BP
- RETN
- OvrXMSLoad ENDP
-
- OvrInitXMS PROC
-
- ; Make sure the file's been opened
-
- XOR AX, AX
- CMP AX, [OvrDOSHandle]
- JNE @@1
- DEC AX ; ovrError
- JMP @@5
-
- ; Check presence of XMS driver
-
- @@1: MOV AX, 4300h
- INT 2Fh
- CMP AL, 80h
- JE @@2
- MOV AX, ovrNoXmsDriver
- JMP @@5
-
- ; Get XMS driver's entry point
-
- @@2: MOV AX, 4310h
- INT 2Fh
- MOV Word Ptr [XmsDriver], BX
- MOV Word Ptr [XmsDriver+2], ES
- CALL AllocateXms
- JNZ @@3
- MOV AX, ovrNoXMSMemory
- JMP @@5
-
- ; Load the overlay into XMS
-
- @@3: CALL OvrXmsLoad
- JNC @@4
-
- ; An error occurred. Release handle and XMS memory
-
- MOV DX, [OvrXmsHandle]
- MOV AH, 10
- CALL [XmsDriver]
- MOV AX, ovrIOError
- JMP @@5
-
- ; Close file
-
- @@4: MOV BX, [OvrDOSHandle]
- MOV AH, 3Eh
- INT 21h
-
- ; OvrReadBuf := XmsReadFunc
-
- MOV Word Ptr [OvrReadBuf], Offset XmsReadFunc
- MOV Word Ptr [OvrReadBuf+2], CS
-
- ; ExitSave := ExitProc
- ; ExitProc := OvrXmsExit
-
- LES AX, [ExitProc]
- MOV Word Ptr [ExitSave], AX
- MOV Word Ptr [ExitSave+2], ES
- MOV Word Ptr [ExitProc], Offset OvrXmsExit
- MOV Word Ptr [ExitProc+2], CS
-
- ; Return result of initialisation
-
- XOR AX, AX
- @@5: MOV [OvrResult], AX
- RETF
- OvrInitXMS ENDP
-
- Code ENDS
- END