Contributor: REINHARDT MUELLER 
{
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
 

AltStyle によって変換されたページ (->オリジナル) /