home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!news.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v16i018: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part18/108
- Message-ID: <4301@master.CNA.TEK.COM>
- Date: 28 Jan 93 19:14:22 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2518
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
- Posting-number: Volume 16, Issue 18
- Archive-name: nethack31/Part18
- Supersedes: nethack3p9: Volume 10, Issue 46-102
- Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 18 (of 108)."
- # Contents: src/worn.c sys/msdos/ovlmgr.asm
- # Wrapped by billr@saab on Wed Jan 27 16:08:52 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/worn.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/worn.c'\"
- else
- echo shar: Extracting \"'src/worn.c'\" \(8567 characters\)
- sed "s/^X//" >'src/worn.c' <<'END_OF_FILE'
- X/* SCCS Id: @(#)worn.c 3.1 92/12/13
- X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X#include "hack.h"
- X
- Xstatic void FDECL(rel_1_obj, (struct monst *,struct obj *));
- X
- Xconst struct worn {
- X long w_mask;
- X struct obj **w_obj;
- X} worn[] = {
- X { W_ARM, &uarm },
- X { W_ARMC, &uarmc },
- X { W_ARMH, &uarmh },
- X { W_ARMS, &uarms },
- X { W_ARMG, &uarmg },
- X { W_ARMF, &uarmf },
- X#ifdef TOURIST
- X { W_ARMU, &uarmu },
- X#endif
- X { W_RINGL, &uleft },
- X { W_RINGR, &uright },
- X { W_WEP, &uwep },
- X { W_AMUL, &uamul },
- X { W_TOOL, &ublindf },
- X { W_BALL, &uball },
- X { W_CHAIN, &uchain },
- X { 0, 0 }
- X};
- X
- Xvoid
- Xsetworn(obj, mask)
- Xregister struct obj *obj;
- Xlong mask;
- X{
- X register const struct worn *wp;
- X register struct obj *oobj;
- X
- X for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) {
- X oobj = *(wp->w_obj);
- X if(oobj && !(oobj->owornmask & wp->w_mask))
- X impossible("Setworn: mask = %ld.", wp->w_mask);
- X if(oobj) {
- X oobj->owornmask &= ~wp->w_mask;
- X /* leave as "x = x <op> y", here and below, for broken
- X * compilers */
- X u.uprops[objects[oobj->otyp].oc_oprop].p_flgs =
- X u.uprops[objects[oobj->otyp].oc_oprop].p_flgs &
- X ~wp->w_mask;
- X if (oobj->oartifact) set_artifact_intrinsic(oobj, 0, mask);
- X }
- X *(wp->w_obj) = obj;
- X if(obj) {
- X obj->owornmask |= wp->w_mask;
- X /* prevent getting intrinsics from wielding potions, etc... */
- X /* wp_mask should be same as mask at this point */
- X if(obj->oclass == WEAPON_CLASS || mask != W_WEP) {
- X u.uprops[objects[obj->otyp].oc_oprop].p_flgs =
- X u.uprops[objects[obj->otyp].oc_oprop].p_flgs |
- X wp->w_mask;
- X if (obj->oartifact) set_artifact_intrinsic(obj,1,mask);
- X } else if(obj->oartifact)
- X set_artifact_intrinsic(obj,1,mask);
- X }
- X }
- X}
- X
- X/* called e.g. when obj is destroyed */
- Xvoid
- Xsetnotworn(obj)
- Xregister struct obj *obj;
- X{
- X register const struct worn *wp;
- X
- X if (!obj) return;
- X for(wp = worn; wp->w_mask; wp++)
- X if(obj == *(wp->w_obj)) {
- X *(wp->w_obj) = 0;
- X u.uprops[objects[obj->otyp].oc_oprop].p_flgs =
- X u.uprops[objects[obj->otyp].oc_oprop].p_flgs &
- X ~wp->w_mask;
- X obj->owornmask &= ~wp->w_mask;
- X if (obj->oartifact)
- X set_artifact_intrinsic(obj, 0, wp->w_mask);
- X }
- X}
- X
- X#ifdef MUSE
- Xint
- Xfind_mac(mon)
- Xregister struct monst *mon;
- X{
- X register struct obj *obj;
- X int base = mon->data->ac;
- X long mwflags = mon->misc_worn_check;
- X
- X for(obj = mon->minvent; obj; obj = obj->nobj) {
- X if (obj->owornmask & mwflags)
- X base -= ARM_BONUS(obj);
- X }
- X return base;
- X}
- X
- X/* Wear first object of that type it finds, and never switch unless it
- X * has none at all. This means that monsters with leather armor never
- X * switch to plate mail, but it also avoids the overhead of having seven
- X * struct obj *s for every monster in the game, more if we ever extend this.
- X */
- Xvoid
- Xm_dowear(mon, creation)
- Xregister struct monst *mon;
- Xboolean creation;
- X{
- X register struct obj *obj;
- X
- X /* Note the restrictions here are the same as in dowear in do_wear.c
- X * except for the additional restriction on intelligence. (Players
- X * are always intelligent, even if polymorphed).
- X */
- X if (verysmall(mon->data) || nohands(mon->data)) return;
- X if (is_animal(mon->data) || mindless(mon->data)) return;
- X
- X for(obj = mon->minvent; obj; obj = obj->nobj) {
- X long flag;
- X
- X# ifdef TOURIST
- X if (obj->otyp == HAWAIIAN_SHIRT) flag = W_ARMU;
- X else
- X# endif
- X if (is_cloak(obj)) flag = W_ARMC;
- X else if (is_helmet(obj)) flag = W_ARMH;
- X else if (is_shield(obj)) {
- X if (MON_WEP(mon) && bimanual(MON_WEP(mon)))
- X continue;
- X flag = W_ARMS;
- X } else if (is_gloves(obj)) {
- X if (MON_WEP(mon) && MON_WEP(mon)->cursed)
- X continue;
- X flag = W_ARMG;
- X } else if (is_boots(obj)) flag = W_ARMF;
- X else if (obj->oclass == ARMOR_CLASS) {
- X#ifdef POLYSELF
- X if (cantweararm(mon->data))
- X continue;
- X#endif
- X flag = W_ARM;
- X } else continue;
- X if (mon->misc_worn_check & flag) continue;
- X /* already wearing one */
- X if (!creation && canseemon(mon)) {
- X pline("%s puts on %s.", Monnam(mon),
- X distant_name(obj, doname));
- X mon->mfrozen = objects[obj->otyp].oc_delay;
- X if (mon->mfrozen) mon->mcanmove = 0;
- X }
- X mon->misc_worn_check |= flag;
- X obj->owornmask |= flag;
- X }
- X}
- X
- Xstruct obj *
- Xwhich_armor(mon, flag)
- Xstruct monst *mon;
- Xlong flag;
- X{
- X register struct obj *obj;
- X
- X for(obj = mon->minvent; obj; obj = obj->nobj)
- X if (obj->owornmask & flag) return obj;
- X return((struct obj *)0);
- X}
- X
- Xstatic void
- Xrel_1_obj(mon, obj)
- Xstruct monst *mon;
- Xstruct obj *obj;
- X{
- X struct obj *otmp;
- X struct obj *backobj = (struct obj *)0;
- X
- X for(otmp = mon->minvent; otmp; otmp = otmp->nobj) {
- X if (obj == otmp) {
- X if (!backobj) mon->minvent = otmp->nobj;
- X else backobj->nobj = otmp->nobj;
- X place_object(otmp, mon->mx, mon->my);
- X otmp->nobj = fobj;
- X fobj = otmp;
- X if (cansee(mon->mx, mon->my)) newsym(mon->mx, mon->my);
- X return;
- X }
- X backobj = otmp;
- X }
- X impossible("%s has %s missing?", Monnam(mon), xname(obj));
- X}
- X
- Xvoid
- Xmon_break_armor(mon)
- Xstruct monst *mon;
- X{
- X register struct obj *otmp;
- X struct permonst *mdat = mon->data;
- X boolean vis = cansee(mon->mx, mon->my);
- X const char *pronoun, *ppronoun;
- X
- X switch(gender(mon)) {
- X case 0: pronoun = "him"; ppronoun = "his"; break;
- X case 1: pronoun = ppronoun = "her"; break;
- X default: pronoun = "it"; ppronoun = "its"; break;
- X }
- X if (breakarm(mdat)) {
- X if (otmp = which_armor(mon, W_ARM)) {
- X if (vis)
- X pline("%s breaks out of %s armor!", Monnam(mon), ppronoun);
- X else
- X You("hear a cracking sound.");
- X mon->misc_worn_check &= ~W_ARM;
- X m_useup(mon, otmp);
- X }
- X if (otmp = which_armor(mon, W_ARMC)) {
- X if (otmp->oartifact) {
- X if (vis)
- X pline("%s cloak falls off!", s_suffix(Monnam(mon)));
- X mon->misc_worn_check &= ~W_ARMC;
- X otmp->owornmask &= ~W_ARMC;
- X rel_1_obj(mon, otmp);
- X } else {
- X if (vis)
- X pline("%s cloak tears apart!", s_suffix(Monnam(mon)));
- X else
- X You("hear a ripping sound.");
- X mon->misc_worn_check &= ~W_ARMC;
- X m_useup(mon, otmp);
- X }
- X }
- X# ifdef TOURIST
- X if (otmp = which_armor(mon, W_ARMU)) {
- X if (vis)
- X pline("%s shirt rips to shreds!", s_suffix(Monnam(mon)));
- X else
- X You("hear a ripping sound.");
- X mon->misc_worn_check &= ~W_ARMU;
- X m_useup(mon, otmp);
- X }
- X# endif
- X } else if (sliparm(mdat)) {
- X if (otmp = which_armor(mon, W_ARM)) {
- X if (vis)
- X pline("%s armor falls around %s!",
- X s_suffix(Monnam(mon)), pronoun);
- X else
- X You("hear a thud.");
- X mon->misc_worn_check &= ~W_ARM;
- X otmp->owornmask &= ~W_ARM;
- X rel_1_obj(mon, otmp);
- X }
- X if (otmp = which_armor(mon, W_ARMC)) {
- X if (vis)
- X if (is_whirly(mon->data))
- X pline("%s cloak falls, unsupported!",
- X s_suffix(Monnam(mon)));
- X else
- X pline("%s shrinks out of %s cloak!", Monnam(mon),
- X ppronoun);
- X mon->misc_worn_check &= ~W_ARMC;
- X otmp->owornmask &= ~W_ARMC;
- X rel_1_obj(mon, otmp);
- X }
- X# ifdef TOURIST
- X if (otmp = which_armor(mon, W_ARMU)) {
- X if (vis)
- X if (sliparm(mon->data))
- X pline("%s seeps right through %s shirt!",
- X Monnam(mon), ppronoun);
- X else
- X pline("%s becomes much too small for %s shirt!",
- X Monnam(mon), ppronoun);
- X mon->misc_worn_check &= ~W_ARMU;
- X otmp->owornmask &= ~W_ARMU;
- X rel_1_obj(mon, otmp);
- X }
- X# endif
- X }
- X if (nohands(mdat) || verysmall(mdat)) {
- X if (otmp = which_armor(mon, W_ARMG)) {
- X if (vis)
- X pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,
- X MON_WEP(mon) ? " and weapon" : "");
- X possibly_unwield(mon);
- X mon->misc_worn_check &= ~W_ARMG;
- X otmp->owornmask &= ~W_ARMG;
- X rel_1_obj(mon, otmp);
- X }
- X if (otmp = which_armor(mon, W_ARMS)) {
- X if (vis)
- X pline("%s can no longer hold %s shield!", Monnam(mon),
- X ppronoun);
- X else
- X You("hear a clank.");
- X mon->misc_worn_check &= ~W_ARMS;
- X otmp->owornmask &= ~W_ARMS;
- X rel_1_obj(mon, otmp);
- X }
- X if (otmp = which_armor(mon, W_ARMH)) {
- X if (vis)
- X pline("%s helmet falls to the floor!",
- X s_suffix(Monnam(mon)));
- X else
- X You("hear a clank.");
- X mon->misc_worn_check &= ~W_ARMH;
- X otmp->owornmask &= ~W_ARMH;
- X rel_1_obj(mon, otmp);
- X }
- X if (otmp = which_armor(mon, W_ARMF)) {
- X if (vis) {
- X if (is_whirly(mon->data))
- X pline("%s boots fall away!",
- X s_suffix(Monnam(mon)));
- X else pline("%s boots %s off %s feet!",
- X s_suffix(Monnam(mon)),
- X verysmall(mdat) ? "slide" : "are pushed", ppronoun);
- X }
- X mon->misc_worn_check &= ~W_ARMF;
- X otmp->owornmask &= ~W_ARMF;
- X rel_1_obj(mon, otmp);
- X }
- X }
- X}
- X#endif
- X
- X/*worn.c*/
- END_OF_FILE
- if test 8567 -ne `wc -c <'src/worn.c'`; then
- echo shar: \"'src/worn.c'\" unpacked with wrong size!
- fi
- # end of 'src/worn.c'
- fi
- if test -f 'sys/msdos/ovlmgr.asm' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sys/msdos/ovlmgr.asm'\"
- else
- echo shar: Extracting \"'sys/msdos/ovlmgr.asm'\" \(46506 characters\)
- sed "s/^X//" >'sys/msdos/ovlmgr.asm' <<'END_OF_FILE'
- X; SCCS Id: @(#)ovlmgr.asm 91/09/04
- X; Copyright (c) 1989, 1990, 1991, 1992, 1993 Pierre Martineau and
- X; Stephen Spackman. All Rights Reserved.
- X; This product may be freely redistributed. See NetHack license for details.
- X
- XVERSION EQU 3100h
- X
- X PAGE 57,132
- X TITLE 'DOS Overlay Manager for MSC 5.1+'
- X SUBTTL 'Copyright (c) 1989, 1990, 1991, 1992, 1993 Pierre Martineau and Stephen Spackman. All Rights Reserved.'
- X
- X; Multiple overlay file support for v30a0 by Norm Meluch with some input from Stephen.
- X
- X; acknowledgements: - Many thanks to Norm Meluch for his invaluable help
- X; - No thanks to Microsoft
- X; - alltrsidsctysti!!!
- X; - izchak and friends for impetus
- X; - us for brilliance
- X; - coffee for speed
- X; - others as necessary
- X
- X; assumptions: - all registers are preserved including flags
- X; - the stack is preserved
- X; - re-entrancy is not required
- X
- X; options: /Di386 use 80386-specific opcodes
- X; (faster, but no good for weaker machines)
- X; /DNOEMS omit EMS support
- X; (needed if application uses EMS)
- X; /DNOSPLIT omit support for external .OVL files
- X
- XDOSALLOC EQU 48h ; memory allocation
- XDOSFREE EQU 49h ; free allocated memory
- XDOSREALLOC EQU 4ah ; modify memory block
- XDOSREAD EQU 3fh ; read bytes from handle
- XDOSSEEK EQU 42h ; logical handle seek
- XDOSOPEN EQU 3dh ; open handle
- XDOSCLOSE EQU 3eh ; close handle
- XDOSSETDTA EQU 1ah ; Set Data transfer area
- XDOSGETDTA EQU 2fh ; Get Data transfer area
- XDOSSEARCH EQU 4eh ; Search for 1st file match
- XDOSNEXTFILE EQU 4fh ; Search for next file match
- XDOSEXEC EQU 4bh ; exec child process
- XDOSPUTC EQU 02h ; print a char
- XDOSVERSION EQU 30h ; get version number
- XDOSGETVEC EQU 35h ; get interrupt vector
- XDOSGETSWITCH EQU 3700h ; get DOS switchar
- XDOS EQU 21h ; Dos interrupt #
- XPRINT EQU 09h ; print string
- XTERMINATE EQU 4ch ; terminate process
- XEMM EQU 67h ; EMM handler int vector
- XEMMSTATUS EQU 40h ; get EMM status
- XEMMFRAME EQU 41h ; get EMM page frame
- XEMMTOTALS EQU 42h ; get EMM pages available
- XEMMALLOC EQU 43h ; allocate EMM pages
- XEMMMAP EQU 44h ; map EMM pages
- XEMMFREE EQU 45h ; free EMM pages
- XMAXNAMESIZE EQU 50h ; max path name size
- XMAXFILES EQU 0Eh ; max # of *.OVL files
- XEXESIGNUM EQU 5a4dh ; Exe header signature
- XCR EQU 0dh
- XLF EQU 0ah
- XESCAPE EQU 1bh
- XBELL EQU 07h
- XPARSIZ EQU 10h ; this is the size of a paragraph - this better not change!
- XFAERIE EQU 00h ; Used for dummy segment allocation
- X
- XNOERR EQU 0
- XDOSERR EQU 1
- XFILEERR EQU 2
- XNOMEMERR EQU 3
- XFILEIOERR EQU 4
- XVICTIMERR EQU 5
- XRELERR EQU 6
- XEMSERR EQU 7
- XHDRERR EQU 8
- XNAMERR EQU 9
- XOVLERR EQU 10
- XNOHDRERR EQU 11
- X
- X; The following EXTRNs are supplied by the linker
- X
- XEXTRN $$OVLBASE:BYTE ; segment of OVERLAY_AREA
- XEXTRN $$MPGSNOVL:BYTE ; ^ to module table
- XEXTRN $$MPGSNBASE:WORD ; ^ to module segment fixups
- XEXTRN $$INTNO:BYTE ; interrupt number to be used
- XEXTRN $$COVL:WORD ; number of physical overlays
- XEXTRN $$CGSN:WORD ; number of modules
- XEXTRN $$MAIN:FAR ; ^ to function main()
- X
- XPUBLIC $$OVLINIT ; Our entry point
- X ; called by the c startup code
- XIFDEF i386
- XOP32 MACRO ; 32 bit operand override
- X DB 066h
- X ENDM
- X
- Xpusha MACRO ; push all registers
- X DB 060h
- X ENDM
- X
- Xpopa MACRO ; pop all registers
- X DB 061h
- X ENDM
- XENDIF
- X
- Xovlflgrec RECORD locked:1=0,ems:1=0,loaded:1=0,file:4=0,pad:1 ; overlay flags
- X ; "file" is the overlay file this overlay is in; 0 is the .EXE
- X ; itself. Otherwise, the numbers are arbitrary.
- X
- X; This is a dirty hack. What we need is a virtual segment that will be built
- X; by the (our) loader in multiple copies, one per overlay. Unfortunately, this
- X; doesn't seem to be a sensible idea in the minds of the folks at Microsoft.
- X; Declaring this segment AT will ensure that it never appears in the exefile,
- X; and ASSUME is dumb enough to be fooled.
- X;
- X; The reason we want to do this is also not-to-be-tried-at-home: it turns out
- X; that we can code a faster interrupt handler if we map overlay numbers to
- X; segment values. Normally we would consider this unacceptable programming
- X; practise because it is 86-mode specific, but the *need* for this entire
- X; programme is 86-mode specific, anyway.
- X
- Xpspseg SEGMENT PARA AT FAERIE ; dummy segment for psp
- X ORG 2ch ; ^ to segment of environmemt in psp
- Xpspenv LABEL WORD
- Xpspseg ENDS
- X
- Xovltbl SEGMENT PARA AT FAERIE ; Dummy segment definition for overlay table
- X
- X; NOTE: This segment definition MUST be exactly 16 bytes long
- X
- Xovlflg ovlflgrec <0,0,0,0,0> ; overlay flags
- Xovlinvcnt DB ? ; invocation count
- Xovlmemblk DW ? ; ^ to allocated memory block
- Xovllrudat DD ? ; misc lru data (pseudo time stamp)
- Xovlemshdl DW ? ; ovl ems memory handle
- Xovlfiloff DW ? ; ovl file offset in pages (512 bytes)
- Xovlsiz DW ? ; ovl size in paragraphs
- Xovlhdrsiz DW ? ; hdr size in paragraphs
- X
- XIF1
- XIF ($ - ovlflg) GT PARSIZ
- X .ERR
- X %OUT This segment MUST be no more than 16 bytes, REALLY!!!
- XENDIF
- XENDIF
- X
- XOVLSEGSIZ EQU PARSIZ ; this had better be true!!! (16 bytes)
- X
- Xovltbl ENDS
- X
- XDTASTRUC STRUC ; internal DTA for ovlmgr
- X DB 21 DUP (0)
- Xfile_attr DB 0
- Xfile_time DW 0
- Xfile_date DW 0
- Xfile_size DD 0
- Xfile_name DB 9 DUP (0)
- Xfile_ext DB 3 DUP (0)
- Xdtapad DB 86 DUP (0) ; Pad to 128 bytes
- XDTASTRUC ENDS
- X
- XEXEHDR STRUC ; structure of an EXE header
- Xexesign DW EXESIGNUM ; signature
- Xexelstpgesiz DW ? ; last page size (512 byte pages)
- Xexesiz DW ? ; total pages (including partial last page)
- Xrelocitems DW ? ; number of relocation entries
- Xhdrparas DW ? ; number of paragraphs in the header
- Xminalloc DW ? ; minimum paragraph allocation
- Xmaxalloc DW ? ; maximum patagraph allocation
- Xexess DW ? ; initial stack segment
- Xexesp DW ? ; initial stack pointer
- Xexechksum DW ? ; checksum
- Xexeip DW ? ; initial instruction pointer
- Xexecs DW ? ; initial code segment
- Xreloctbloff DW ? ; offset from beginning of header to relocation table
- Xexeovlnum DW ? ; overlay number
- XEXEHDR ENDS
- X
- XMASK_used EQU 1 ; memory block flag
- X
- XMEMCTLBLK STRUC ; memory block structure
- Xmemblkflg DB ? ; flags
- Xmemblkpad1 DB ? ; go ahead, delete me!
- Xmemblknxt DW ? ; ^ to next block
- Xmemblkprv DW ? ; ^ to previous block
- Xmemblkovl DW ? ; ^ to overlay occupying this block
- Xmemblksiz DW ? ; size in paragraphs
- Xmemblkpad DB PARSIZ - memblkpad MOD PARSIZ DUP (?) ; pad to 16 bytes
- XMEMCTLBLK ENDS
- X
- XMEMCTLBLKSIZ EQU TYPE MEMCTLBLK / PARSIZ ; should equal 1 paragraph
- X
- X;-------------------------------------------------------------------------------
- X
- Xcode SEGMENT PUBLIC
- X
- X; NOTE: the following order is optimum for alignment purposes across the
- X; entire INTEL 80x86 family of processors.
- X
- Xovltim DD ? ; pseudo-lru time variable
- Xfarcall DD ? ; internal trampoline.
- Xoldvec DD -1 ; saved interrupt vector
- Xoldint21 DD -1 ; saved int 21 vector
- Xsireg DW ? ; temp save area
- XIFDEF i386
- X DW ? ; for esi
- XENDIF
- Xdsreg DW ? ; temp save area
- Xssreg DW ?
- Xspreg DW ?
- Xovlfilhdl DW MAXFILES+1 DUP (-1) ; always-open file handles for .EXE, .OVL
- Xovltblbse DW -1 ; segment of first overlay descriptor
- Xmemblks DW 16 DUP (-1) ; allocated memory blocks
- Xmemblk1st DW ? ; first memory block
- Xemsmemblks DW 16 DUP (-1) ; ems allocated memory blocks (64K each)
- Xcuremshandle DW -1 ; currently mapped handle
- Xovlcnt DW ? ; # overlays
- Xmodcnt DW ? ; # of modules
- Xovlrootcode DW ? ; logical segment of OVERLAY_AREA
- Xovldata DW ? ; logical segment of OVERLAY_END
- Xpspadd DW ? ; our psp address + 10h (for relocations)
- Xemsframe DW ? ; EMM page frame segment
- Xmoduletbl DD 256 DUP (?) ; module lookup table (256 modules)
- Xcurovl DW OFFSET stkframe ; ^ into stack frame
- Xstkframe DW 256*3 DUP (?) ; internal stack (256 ovls deep)
- Xtempmem DW 16 DUP (-1) ; temp mem block storage
- Xintnum DW ? ; ovlmgr int number
- Xhdr EXEHDR <> ; EXE header work area
- X DB 512-TYPE EXEHDR DUP (?) ; exe hdr buffer for relocations
- XEXEHDRTMPSIZ EQU $ - hdr ; size of temp reloc buffer
- Xfilestring DB MAXNAMESIZE DUP (0) ; string space for file specs
- Xpathlen DW ? ; path length of file spec
- Xnamelen DW ? ; length of file names
- Xovldta DTASTRUC <> ; DTA for ovlmgr use
- Xdtaseg DW ? ; DTA segment for program
- Xdtaoffset DW ? ; DTA offset for program
- Xerrortbl DW -1 ; error message pointers
- X DW OFFSET baddos
- X DW OFFSET nofile
- X DW OFFSET noroom
- X DW OFFSET badio
- X DW OFFSET nocore
- X DW OFFSET nocore
- X DW OFFSET badems
- X DW OFFSET badhdr
- X DW OFFSET badnam
- X DW OFFSET noovl
- X DW OFFSET nohdr
- X DW OFFSET unknown
- X DW OFFSET unknown
- X DW OFFSET unknown
- X DW OFFSET unknown
- Xemmname DB "EMMXXXX0" ; EMM device driver name
- Xemmtot DW 0 ; total emm blocks free
- Xemmframesiz DW 4 ; frame size in blocks
- Xemmflg DB 0 ; EMM present flag
- X
- Xi386code DB '386 specific code enabled.',CR,LF,'$'
- Xmemavl DB 'Conventional memory available: $'
- Xparagraphs DB 'H paragraphs.',CR,LF,'$'
- Xemsavl DB 'EMS memory available: $'
- Xpages DB 'H 16K-pages.',CR,LF,'$'
- Xbaddos DB 'Incorrect DOS version. Must be 3.00 or later.$'
- Xnofile DB 'Inaccessible EXE file. Can',39,'t load overlays.$'
- Xnoroom DB 'Not enough free memory left to run this program.$'
- Xbadio DB 'File I/O error.$'
- Xnocore DB 'Internal memory allocation failure.$'
- Xbadems DB 'EMS memory manager error.$'
- Xbadhdr DB 'Executable or overlay header missing or damaged.$'
- Xbadnam DB 'Unable to resolve overlay file names.$'
- Xnoovl DB 'Inaccessible OVL file. Can',39,'t load overlays.$'
- Xnohdr DB 'Incomplete executable. OVL files missing?$'
- Xunknown DB 'Unknown error!$'
- Xmsghead DB ESCAPE,'[0m',ESCAPE,'[K',CR,LF,ESCAPE,'[K',ESCAPE,'[1mOVLMGR:',ESCAPE,'[0m $'
- Xdiag DB ESCAPE,'[K',CR,LF,ESCAPE,'[K',' ($'
- Xmsgtail DB ESCAPE,'[K',CR,LF,ESCAPE,'[K',BELL,'$'
- Xovlext DB '?.OVL',0
- X
- X;-------------------------------------------------------------------------------
- X
- X$$OVLINIT PROC FAR ; Init entry point
- X
- X ASSUME CS:code,DS:pspseg,ES:NOTHING
- X
- X push ax
- X push bx
- X push cx
- X push dx
- X push si
- X push di
- X push bp
- X push ds
- X push es ; save the world
- X
- X cld
- X mov ax,ds ; get our psp
- X add ax,10h
- X mov pspadd,ax ; save it
- X mov ah,DOSVERSION
- X int DOS
- X cmp al,3 ; DOS 3.0 or later
- X jnc doenvthing
- X mov al,DOSERR ; incorrect version of dos
- X jmp putserr
- Xdoenvthing:
- X mov ds,pspenv ; get environment segment
- X mov si,-1
- Xenvloop: ; search for end of environment
- X inc si
- X cmp WORD PTR [si],0
- X jnz envloop
- X add si,4 ; point to EXE filename
- X
- X call openfiles ; Search & open overlay files
- XIFNDEF NOEMS
- Xchkems:
- X mov ah,DOSGETVEC
- X mov al,EMM
- X int DOS
- X mov ax,cs
- X mov ds,ax
- X mov di,0ah
- X mov si,OFFSET emmname
- X mov cx,8
- X repe cmpsb
- X mov al,0
- X jnz setemmflg
- X mov al,-1
- Xsetemmflg:
- X mov emmflg,al
- X jnz noemshere
- X mov ah,EMMFRAME
- X int EMM
- X mov emsframe,bx
- X mov ah,EMMTOTALS
- X int EMM
- X mov emmtot,bx
- Xnoemshere:
- XENDIF
- X mov ax,SEG $$OVLBASE ; OVERLAY_AREA segment
- X mov ovlrootcode,ax
- X mov ax,SEG $$COVL ; segment of DGROUP
- X mov ds,ax
- X mov bx,$$CGSN ; number of modules
- X mov modcnt,bx ; save for later use
- X mov bx,$$COVL ; number of physical overlays
- X mov ovlcnt,bx ; save for later use
- X
- X; Now allocate memory
- X mov ah,DOSALLOC ; bx contains # paras needed for ovltbl
- X int DOS
- X jnc gotovlram
- X jmp buyram
- Xgotovlram:
- X mov ovltblbse,ax ; overlay descriptor table begins at start of memory block
- X
- X mov cx,ovlcnt
- Xzeromem:
- X mov es,ax
- X mov es:ovlflg,0 ; initialise ovl flags
- X mov es:ovlinvcnt,0 ; initialise invocation count
- X mov es:ovlmemblk,0
- X mov WORD PTR es:ovllrudat,0 ; initialise ovl lru
- X mov WORD PTR es:ovllrudat+2,0
- X mov es:ovlemshdl,-1
- X mov es:ovlfiloff,0 ; initialize file offset
- X mov es:ovlsiz,0 ; initialize overlay size
- X mov es:ovlhdrsiz,0
- X inc ax
- X loop zeromem
- X
- X mov ax,cs
- X mov ds,ax
- XIFDEF DEBUG
- XIFDEF i386
- X mov ah,print
- X mov dx,OFFSET msghead
- X int DOS
- X mov ah,print
- X mov dx,OFFSET i386code
- X int DOS
- XENDIF
- X mov ah,print
- X mov dx,OFFSET msghead
- X int DOS
- X mov ah,print
- X mov dx,OFFSET memavl
- X int DOS
- X mov ax,0a000h
- X sub ax,ovltblbse
- X call itoa
- X mov ah,print
- X mov dx,OFFSET paragraphs
- X int DOS
- XIFNDEF NOEMS
- X mov ah,print
- X mov dx,OFFSET msghead
- X int DOS
- X mov ah,print
- X mov dx,OFFSET emsavl
- X int DOS
- X mov ax,emmtot
- X call itoa
- X mov ah,print
- X mov dx,OFFSET pages
- X int DOS
- XENDIF
- XENDIF
- X ASSUME ES:ovltbl
- X
- X xor bp,bp
- X xor di,di
- X xor si,si ; file handle loop ctr
- Xfilsegtbllpp: ; initialise ovl table
- X call gethdr ; get an EXE header
- X
- X mov ax,ovltblbse
- X add ax,hdr.exeovlnum
- X mov es,ax ; ^ to ovl table entry
- XIFNDEF NOSPLIT
- X mov cx,si ; set file # in ovlflg
- X shl cx,1
- X mov ovlflg,cl
- XENDIF
- X mov ax,hdr.exesiz
- X shl ax,1
- X shl ax,1
- X shl ax,1
- X shl ax,1
- X shl ax,1 ; * 32
- X mov dx,hdr.exelstpgesiz
- X or dx,dx
- X jz emptypage
- X shr dx,1
- X shr dx,1
- X shr dx,1
- X shr dx,1 ; / 16
- X inc dx
- X sub ax,20h
- X add ax,dx
- Xemptypage:
- X sub ax,hdr.hdrparas ; actual size of code
- X mov ovlsiz,ax ; overlay size in paragraphs
- X cmp hdr.exeovlnum,0 ; skip if ovl 0 (root code)
- X jz notlargest
- X cmp ax,di ; find largest ovl
- X jc notlargest
- X mov di,ax
- Xnotlargest:
- X mov ax,hdr.hdrparas
- X shl ax,1
- X shl ax,1
- X shl ax,1
- X shl ax,1
- X mov ovlhdrsiz,ax ; hdr size in bytes
- X mov ovlfiloff,bp ; initialise ovl file offset
- X add bp,hdr.exesiz ; ^ to next overlay
- X mov dx,bp
- X mov cl,dh
- X mov dh,dl
- X xor ch,ch
- X xor dl,dl
- X shl dx,1
- X rcl cx,1 ; cx:dx = bp * 512
- X mov al,0
- X mov ah,DOSSEEK ; seek to next ovl
- X int DOS
- X
- X mov cx,ovlcnt ; check if all overlays found
- X mov ax,ovltblbse
- X dec cx ; ovlcnt includes root
- X add ax,cx
- Xovloop:
- X mov es,ax
- XIFNDEF NOSPLIT
- X mov bl,ovlflg
- X and bx,MASK file
- X
- X cmp bx,0 ; if file # is 0
- X jne again
- XENDIF
- X cmp ovlfiloff,0 ; and offset is 0
- X jne again
- X jmp filsegtbllpp ; then we're still looking
- Xagain:
- X dec ax
- X loop ovloop
- X
- X ASSUME ES:nothing ; prepare first memory block
- X
- X mov ax,ovlrootcode ; OVERLAY_AREA segment
- X mov memblk1st,ax ; save pointer to first mem block
- X mov es,ax
- X mov es:memblkflg,0 ; clear mem flags
- X mov es:memblknxt,0 ; set next to nothing
- X mov es:memblkprv,0 ; set previous to nothing
- X mov es:memblkovl,0 ; no overlay loaded
- X mov es:memblksiz,di ; di contains OVERLAY_AREA size in paragraphs
- X add ax,di
- X mov ovldata,ax ; end of OVERLAY_END
- X push di
- X mov es,ovltblbse ; temporary
- X call getemsmem ; see if any ems available
- X mov es:ovlemshdl,-1 ; fix these!
- X and es:ovlflg,NOT MASK ems
- X push dx
- X call getmoreram ; see if there are any other pieces lying around
- X pop ax
- X pop di
- X or ax,ax ; any ems?
- X jnz noramcheck
- X inc di
- X cmp dx,di
- X jc buyram
- Xnoramcheck:
- X mov WORD PTR ovltim,0 ; initialise global lru time stamp
- X mov WORD PTR ovltim+2,0
- X mov di,OFFSET stkframe
- X mov WORD PTR cs:[di],-1 ; initialise stack frame
- X add di,6
- X mov ax,ovltblbse
- X mov cs:[di],ax
- X mov curovl,di ; initialise stack frame pointer
- X mov es,ax
- X mov es:ovlflg,MASK locked OR MASK loaded ; set flags on ovl 0
- X jmp short chgintvec
- Xbuyram:
- X mov al,NOMEMERR ; free up some TSRs or something
- X jmp putserr
- Xchgintvec:
- X mov ax,SEG $$INTNO
- X mov ds,ax
- X mov al,$$INTNO ; get int number to use
- X xor ah,ah
- X shl ax,1
- X shl ax,1
- X mov intnum,ax
- X call setvectors ; set up interrupt vectors
- X mov cx,modcnt ; module count
- X mov ax,SEG $$MPGSNBASE
- X mov es,ax
- X mov ax,cs
- X mov ds,ax
- X
- X ASSUME DS:code
- X
- X mov bx,OFFSET $$MPGSNBASE ; ^ to linker provided overlay segment fixups
- X mov si,OFFSET $$MPGSNOVL ; ^ to linker provided module table
- X mov di,OFFSET moduletbl ; ^ to our module table
- Xmodloop:
- X mov al,es:[si] ; real physical ovl number
- X xor ah,ah
- X add ax,ovltblbse ; ovlctlseg address
- X mov [di],ax ; save in module table
- X mov ax,es:[bx] ; get seg fixup
- X sub ax,ovlrootcode ; adjust for relative reference
- X mov [di+2],ax ; save in module table
- X add di,4
- X add bx,2
- X inc si
- X loop modloop
- X pop es
- X pop ds
- X pop bp
- X pop di
- X pop si
- X pop dx
- X pop cx
- X pop bx
- X pop ax ; restore the world
- X jmp $$MAIN ; And away we go!
- X
- X$$OVLINIT ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xovlmgr PROC FAR ; This is the it!
- X
- X ASSUME DS:NOTHING,ES:NOTHING
- X
- XIFDEF i386
- X OP32
- XENDIF
- X mov sireg,si ; preserve si
- X mov dsreg,ds ; and ds
- X pop si ; retrieve caller ip
- X pop ds ; " " cs
- X push ax
- X push bx
- X cld
- X lodsb ; module # to call
- X xor ah,ah
- X mov bx,ax
- X lodsw ; offset in ovl to call
- X mov WORD PTR farcall,ax ; into trampoline
- X mov ax,si
- X mov si,curovl ; get stack frame pointer
- X add si,6 ; update stack
- X mov cs:[si-4],ds ; save return seg
- X mov cs:[si-2],ax ; and return offset
- X
- X shl bx,1
- X shl bx,1 ; * 4 (2 words/entry in module tbl)
- X add bx,OFFSET moduletbl
- X mov ds,cs:[bx] ; ovl tbl entry
- X mov ax,cs:[bx+2] ; segment fixup
- X mov cs:[si],ds ; ovl entry into stack frame
- X mov curovl,si
- X
- X ASSUME DS:ovltbl
- X
- XIFDEF i386
- X OP32
- XENDIF
- X mov si,WORD PTR ovltim ; lru time stamp
- XIFDEF i386
- X OP32
- XENDIF
- X inc si ; time passes!
- XIFDEF i386
- X OP32
- XENDIF
- X mov WORD PTR ovltim,si ; update global clock
- XIFDEF i386
- X OP32
- XENDIF
- X mov WORD PTR ovllrudat,si ; as well as ovl clock
- XIFNDEF i386
- X mov si,WORD PTR ovltim+2
- X jz ininc ; dword increment
- Xcryupcdon:
- X mov WORD PTR ovllrudat+2,si ; as well as ovl clock
- XENDIF
- X test ovlflg,MASK loaded ; ovl loaded?
- X jz inload ; load it or map it then.
- Xovlloadedupc:
- X inc ovlinvcnt
- X add ax,ovlmemblk ; add fixup and segment address
- X mov WORD PTR farcall+2,ax ; into trampoline
- XIFDEF i386
- X OP32
- XENDIF
- X mov si,sireg ; retore all registers
- X mov ds,dsreg
- X pop bx
- X pop ax
- X popf ; don't forget these!
- X call DWORD PTR farcall ; and GO
- X pushf ; preserve registers again!
- X mov dsreg,ds
- XIFDEF i386
- X OP32
- XENDIF
- X mov sireg,si
- X mov si,curovl ; stack frame pointer
- X mov ds,cs:[si]
- X dec ovlinvcnt
- X sub si,6 ; adjust stack
- X mov ds,cs:[si] ; retrieve ovl tbl entry
- X push cs:[si+2] ; set return address
- X push cs:[si+4]
- X mov curovl,si
- XIFDEF i386
- X OP32
- XENDIF
- X mov si,WORD PTR ovltim ; do the lru thing again
- XIFDEF i386
- X OP32
- XENDIF
- X inc si
- XIFDEF i386
- X OP32
- XENDIF
- X mov WORD PTR ovltim,si
- XIFDEF i386
- X OP32
- XENDIF
- X mov WORD PTR ovllrudat,si
- XIFNDEF i386
- X mov si,WORD PTR ovltim+2
- X jz outinc
- Xcrydncdon:
- X mov WORD PTR ovllrudat+2,si
- XENDIF
- X test ovlflg,MASK loaded ; ovl loaded?
- X jz outload ; better get it before someone notices
- Xjmpback:
- XIFDEF i386
- X OP32
- XENDIF
- X mov si,sireg ; get registers back
- X mov ds,dsreg
- X iret ; and GO back
- X
- XIFNDEF i386
- Xininc:
- X inc si
- X mov WORD PTR ovltim+2,si ; update global and
- X jmp cryupcdon
- XENDIF
- X
- Xinload:
- X test ovlflg,MASK ems
- X jz infile
- X push ax
- X mov ax,ovlemshdl
- X call mappage
- X pop ax
- X jmp ovlloadedupc
- Xinfile:
- X call loadoverlay ; self explanatory
- X jmp ovlloadedupc
- X
- XIFNDEF i386
- Xoutinc:
- X inc si
- X mov WORD PTR ovltim+2,si
- X jmp crydncdon
- XENDIF
- X
- Xoutload:
- X test ovlflg,MASK ems
- X jz outfile
- X push ax
- X mov ax,ovlemshdl
- X call mappage
- X pop ax
- X jmp jmpback
- Xoutfile:
- X call loadoverlay
- X jmp jmpback
- X
- Xovlmgr ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xloadoverlay PROC NEAR ; load overlay pointed to by es
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- XIFDEF i386
- X OP32
- X pusha ; eax,ecx,edx,ebx,esp,ebp,esi,edi
- XELSE
- X push ax
- X push cx
- X push dx
- X push bx
- X push bp
- X push si
- X push di
- XENDIF
- X push ds
- X push es ; just in case
- X mov ax,ds
- X mov es,ax
- X cmp ovlinvcnt,0
- X jnz fxdadr ; Yup, it's a toughie
- X mov ax,ovlsiz ; How much?
- X call getpages ; never fail mem alloc, you bet.
- X jmp gleaner
- Xfxdadr:
- X call releasepages ; free memory where this ovl should be loaded
- Xgleaner:
- X add ax,MEMCTLBLKSIZ ; skip mem ctl blk
- X mov ovlmemblk,ax ; memory block to use
- X mov ds,ax
- X mov dx,ovlfiloff ; where in the file is it?
- X mov cl,dh
- X mov dh,dl
- X xor ch,ch
- X xor dl,dl
- X shl dx,1
- X rcl cx,1 ; cx:dx = dx * 512
- X mov ax,ovlhdrsiz
- X push cx
- X push dx
- X add dx,ax
- X adc cx,0 ; position to code
- X mov ah,DOSSEEK ; lseek to code
- X mov al,0 ; from beginning of file
- X mov bl,ovlflg
- X and bx,MASK file
- X mov bx,ovlfilhdl[bx] ; never closing handle
- X int DOS
- X jc burnhead ; oops!
- X xor dx,dx ; buf = ds:0
- X mov cx,ovlsiz ; number of paragraphs to load
- X shl cx,1
- X shl cx,1
- X shl cx,1
- X shl cx,1 ; * 16 = number of bytes
- X mov ah,DOSREAD ; prevent random DOS behaviour
- X int DOS ; read in code
- X jc burnhead ; double oops!
- X pop dx
- X pop cx ; position of hdr
- X mov ah,DOSSEEK ; lseek to hdr
- X mov al,0 ; from beginning of file
- X mov bl,ovlflg
- X and bx,MASK file
- X mov bx,ovlfilhdl[bx] ; never closing handle
- X int DOS
- X jc burnhead ; oops!
- X mov cx,EXEHDRTMPSIZ ; reloc buffer size
- X mov dx,OFFSET hdr
- X push ds
- X mov ax,cs
- X mov ds,ax
- X mov ah,DOSREAD ; prevent random DOS behaviour
- X int DOS ; read in header
- X pop ds
- X jc burnhead ; double oops!
- X
- X call ovlrlc ; perform relocation normally done by DOS EXE loader
- X pop es ; retrieve ovl tbl entry
- X pop ds
- X
- X ASSUME DS:ovltbl,ES:NOTHING
- X
- X or ovlflg,MASK loaded ; because it is now
- XIFDEF i386
- X OP32
- X popa
- XELSE
- X pop di
- X pop si
- X pop bp
- X pop bx
- X pop dx
- X pop cx
- X pop ax
- XENDIF
- X ret
- X
- Xburnhead:
- X mov al,FILEIOERR ; some kind of I/O error
- X jmp putserr
- X
- Xloadoverlay ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xovlrlc PROC NEAR ; ds:0 -> the overlay to relocate
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X mov si,OFFSET hdr
- X mov bp,si
- X add bp,EXEHDRTMPSIZ ; ^ to end of buf+1
- X mov cx,cs:[si.relocitems] ; roto-count
- X jcxz relocdone ; not such a good idea, after all
- X mov di,ds
- X sub di,ovlrootcode ; segment fixup value
- X add si,cs:[si.reloctbloff] ; ^ relocation table
- Xdorelocs: ; labels don't GET comments
- X cmp si,bp ; past the end ?
- X jc getoffsetl
- X call getnxtreloc ; get another hunk
- Xgetoffsetl:
- X mov bl,cs:[si] ; offset into load module
- X inc si
- X cmp si,bp ; past the end ?
- X jc getoffseth
- X call getnxtreloc ; get another hunk
- Xgetoffseth:
- X mov bh,cs:[si] ; offset into load module
- X inc si
- X cmp si,bp ; past the end ?
- X jc getsegmentl
- X call getnxtreloc ; get another hunk
- Xgetsegmentl:
- X mov al,cs:[si] ; segment in load module (zero reference)
- X inc si
- X cmp si,bp ; past the end ?
- X jc getsegmenth
- X call getnxtreloc ; get another hunk
- Xgetsegmenth:
- X mov ah,cs:[si] ; segment in load module (zero reference)
- X inc si
- X add ax,pspadd ; now it is psp relative
- X add ax,di ; and now it is relative to the actual load address
- X mov ds,ax
- X mov ax,[bx] ; pickup item to relocate
- X add ax,pspadd ; make it psp relative
- X cmp ax,ovlrootcode ; is it below the OVERLAY_AREA?
- X jc reloccomputed ; yup. it's relocated
- X cmp ax,ovldata ; is it above OVERLAY_AREA
- X jnc reloccomputed ; yup. it's relocated
- X add ax,di ; it's in OVERLAY_AREA, this one's ours.
- Xreloccomputed:
- X mov [bx],ax ; RAM it home!?!
- X loop dorelocs ; what goes around, comes around.
- Xrelocdone: ret
- X
- Xovlrlc ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xgetnxtreloc PROC NEAR
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X push bx
- X push cx
- X push di
- X push bp
- X push ds
- X push es
- X mov cx,EXEHDRTMPSIZ ; reloc buffer size
- X mov dx,OFFSET hdr
- X mov ax,cs
- X mov ds,ax
- X mov bl,ovlflg
- X and bx,MASK file
- X mov bx,ovlfilhdl[bx] ; never closing handle
- X mov ah,DOSREAD ; prevent random DOS behaviour
- X int DOS ; read in header
- X jnc nxtrelocok
- X jmp burnhead ; double oops!
- Xnxtrelocok:
- X mov si,OFFSET hdr
- X pop es
- X pop ds
- X pop bp
- X pop di
- X pop cx
- X pop bx
- X ret
- X
- Xgetnxtreloc ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xgetvictim PROC NEAR ; select a victim to discard (and free up some memory)
- X
- X ASSUME DS:ovltbl,ES:NOTHING
- X
- X push bx
- X push cx
- X push dx
- X push si
- X push di
- X push bp
- X push ds
- X mov ds,ovltblbse ; ^ ovl tbl
- XIFDEF i386
- X OP32
- XENDIF
- X xor ax,ax ; will contain the low word of lru
- XIFDEF i386
- X OP32
- XENDIF
- X mov dx,ax ; will contain the high word of lru
- X mov bp,ax ; will contain ovl tbl entry
- X mov bx,ax ; ovl tbl ptr
- X mov cx,ovlcnt
- Xfoon1:
- X test ovlflg[bx],MASK locked
- X jnz skip1
- X test ovlflg[bx],MASK ems
- X jnz foon2
- X test ovlflg[bx],MASK loaded
- X jz skip1
- Xfoon2:
- XIFDEF i386
- X OP32
- XENDIF
- X mov si,WORD PTR ovltim
- XIFNDEF i386
- X mov di,WORD PTR ovltim+2
- XENDIF
- XIFDEF i386
- X OP32
- XENDIF
- X sub si,WORD PTR ovllrudat[bx]
- XIFNDEF i386
- X sbb di,WORD PTR ovllrudat[bx+2]
- XENDIF
- XIFDEF i386
- X OP32
- X cmp dx,si
- XELSE
- X cmp dx,di
- XENDIF
- XIFDEF i386
- X jnc skip1
- XELSE
- X jc better1
- X jnz skip1
- X cmp ax,si
- X jnc skip1
- XENDIF
- Xbetter1:
- XIFDEF i386
- X OP32
- X mov dx,si
- XELSE
- X mov ax,si
- X mov dx,di
- XENDIF
- X mov bp,bx
- Xskip1:
- X add bx,OVLSEGSIZ
- X loop foon1
- X or bp,bp ; were we more successful this time?
- X jnz gotvictim ; now we got one.
- Xnomoremem:
- X mov al,VICTIMERR ; were really %$# now!
- X jmp putserr
- Xgotvictim:
- X shr bp,1 ; convert offset to segment
- X shr bp,1
- X shr bp,1
- X shr bp,1
- X mov ax,ds
- X add ax,bp
- X pop ds
- X pop bp
- X pop di
- X pop si
- X pop dx
- X pop cx
- X pop bx
- X ret
- X
- Xgetvictim ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xint21 PROC FAR
- X
- X; free almost all overlay memory if app. tries to call the DOS exec function.
- X
- X cmp ah,DOSEXEC
- X jz freeall
- X cmp ah,TERMINATE
- X jz saybyebye
- Xnotours:
- X jmp cs:oldint21
- Xsaybyebye:
- X mov al,NOERR ; return code 0
- X jmp putserr
- Xfreeall:
- X or al,al ; is it load and exec?
- X jnz notours
- X push ax
- X push cx
- X push dx
- X push bx
- X push bp
- X push si
- X push di
- X push es
- X push ds ; preserve calling env.
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X mov es,ovltblbse
- X mov cx,ovlcnt ; unload all overlays that are
- X mov bx,OVLSEGSIZ ; in EMS or are in alloced mem.
- X dec cx
- Xmemunloadlp:
- X test [bx.ovlflg],MASK ems
- X jnz memunload
- X test [bx.ovlflg],MASK loaded
- X jz nxtmemunload
- X mov ax,[bx.ovlmemblk]
- X sub ax,MEMCTLBLKSIZ
- X cmp ax,memblks ; allocated memory ?
- X jc nxtmemunload
- Xmemunload:
- X and [bx.ovlflg],NOT MASK loaded ; you're outta there!
- Xnxtmemunload:
- X add bx,OVLSEGSIZ
- X loop memunloadlp
- X
- X mov curemshandle,-1 ; no current handle anymore
- X
- X mov ax,memblks
- X cmp ax,-1
- X jz nosecondblk
- X mov es,ax ; ^ to second mem blk
- X mov es,es:memblkprv ; get previous pointer
- X mov es:memblknxt,0 ; no other blocks after this one
- Xnosecondblk:
- X mov cx,16 ; do all allocated mem blocks
- X mov si,OFFSET memblks
- Xfreememblklp:
- X mov ax,cs:[si] ; get memory blk segment
- X cmp ax,-1 ; was one ever allocated?
- X jz nxtmemblklp ; nope
- X mov es,ax
- X mov ah,DOSFREE ; must free it.
- X int DOS
- X mov WORD PTR cs:[si],-1
- Xnxtmemblklp:
- X add si,2
- X loop freememblklp
- X
- X call rstvectors ; restore all int vectors
- X
- X mov bp,sp
- X push [bp+22] ; ensure returned flags are based on user's!
- X popf
- X pop ds
- X pop es
- X pop di
- X pop si
- X pop bp
- X pop bx
- X pop dx
- X pop cx
- X pop ax
- X
- X mov ssreg,ss ; preserve these due to a
- X mov spreg,sp ; DOS bug.
- X
- X int DOS ; allow DOS to continue!
- X
- X mov ss,ssreg
- X mov sp,spreg
- X
- X push ax
- X push cx
- X push dx
- X push bx
- X push bp
- X push si
- X push di
- X push es
- X push ds ; preserve calling env.
- X mov bp,sp
- X pushf
- X pop [bp+22] ; fix return flags
- X
- X call getmoreram ; re-allocate our memory
- X call setvectors ; patch vectors again
- X
- X pop ds
- X pop es
- X pop di
- X pop si
- X pop bp
- X pop bx
- X pop dx
- X pop cx
- X pop ax
- X iret
- X
- Xint21 ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xreleasepages PROC NEAR ; Arg in es, result in ax
- X
- X; release any memory (and overlays) where this overlay should reside
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X mov bx,ovlmemblk ; start of memory to release
- X sub bx,MEMCTLBLKSIZ
- X mov dx,bx
- X add dx,es:ovlsiz
- X add dx,MEMCTLBLKSIZ ; end of memory to release
- X mov ax,ovlemshdl
- X cmp ax,-1
- X jz doitagain
- X call mappage
- X or ovlflg,MASK ems
- X mov ax,emsframe
- X jmp dvart
- Xdoitagain:
- X mov ax,memblk1st ; first memory blk
- X jmp dvart
- Xdvartloop:
- X mov ds,ax ; memory blk to check
- X cmp bx,ax ; does it start below the memory to release?
- X jnc dvartsmaller ; yup
- X cmp ax,dx ; does it start above?
- X jnc dvartnocore ; yup
- X call killmem ; it's in the way. Zap it.
- X jmp dvartloop
- Xdvartsmaller:
- X add ax,ds:memblksiz ; end of this memory blk
- X cmp bx,ax ; does it end below the memory to release?
- X jnc dvartsilly ; yup
- X test ds:memblkflg,MASK_used
- X jz dvartfree
- X call killmem ; Oh well, zap it too.
- X add ax,ds:memblksiz ; end of this memory blk
- Xdvartfree:
- X cmp ax,dx ; does it end in the memory to be released?
- X jc dvartsilly
- Xdvartgotblk:
- X mov ax,ds ; this is it!
- X mov cx,bx
- X sub cx,ax ; # of paragraphs between start of memory to release and mem blk
- X jz unsplit
- X push es
- X call splitblk
- X or es:memblkflg,MASK_used ; set high block used
- X call mergemem ; merge remaining free memory
- X mov ax,es
- X mov ds,ax
- X pop es
- Xunsplit:
- X mov cx,es:ovlsiz
- X add cx,MEMCTLBLKSIZ ; paragraphs needed to load ovl
- X jmp splitblklow ; split remaining block
- Xdvartsilly:
- X mov ax,ds:memblknxt
- Xdvart:
- X or ax,ax ; end of mem list?
- X jz dvartnocore
- X jmp dvartloop ; play it again Sam.
- Xdvartnocore:
- X mov al,RELERR ; super OOPS!
- X jmp putserr
- X
- Xreleasepages ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xgetpages PROC NEAR ; get enough memory to load ovl
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X mov ovlemshdl,-1 ; clear any EMS stuff
- X and ovlflg,NOT MASK ems
- X mov cx,ax
- X add cx,MEMCTLBLKSIZ ; total paragraphs needed
- Xdorkagain:
- X call largestmem ; find largest free blk
- X cmp dx,cx ; large enough?
- X jnc gotdork ; yup.
- X call getemsmem ; try to allocate ems
- X cmp dx,cx ; any available ?
- X jnc gotdork
- Xdorkkill:
- X call getvictim ; select a victim to release
- X call killovl ; kill the selected victim
- X jmp dorkagain
- Xgotdork:
- X jmp splitblklow ; split the free blk
- X
- Xgetpages ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xsplitblklow PROC NEAR
- X
- X; split a block of memory returning the lower one to be used.
- X
- X ASSUME DS:NOTHING,ES:NOTHING
- X
- X push es
- X or ds:memblkflg,MASK_used ; set low block used
- X call splitblk
- X jc splitlowdone
- X push ds
- X mov ax,es
- X mov ds,ax
- X call mergemem ; merge remaining free memory
- X pop ds
- Xsplitlowdone:
- X pop es
- X mov ds:memblkovl,es ; fix ptr to ovl
- X mov ax,ds ; return lower blk segment
- X ret
- X
- Xsplitblklow ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xsplitblk PROC NEAR
- X
- X ASSUME DS:NOTHING,ES:NOTHING
- X
- X mov ax,ds
- X add ax,cx
- X mov es,ax ; ^ to upper blk to be created
- X mov ax,ds:memblksiz
- X sub ax,cx
- X jbe nofix ; must be at least 1 para remaining to split
- X mov ds:memblksiz,cx ; fix blk sizes
- X mov es:memblksiz,ax
- X mov ax,ds:memblknxt ; fix pointers
- X mov es:memblknxt,ax
- X mov ds:memblknxt,es
- X mov es:memblkprv,ds
- X mov es:memblkflg,0 ; set upper to not used
- X mov ax,es:memblknxt
- X or ax,ax
- X jz nofix
- X push ds
- X mov ds,ax ; fix blk after upper to point to upper
- X mov ds:memblkprv,es
- X pop ds
- X clc
- X ret
- Xnofix:
- X stc
- X ret
- X
- Xsplitblk ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xlargestmem PROC NEAR ; returns seg in ax, size in dx
- X ; retruns first block that's large enough if possible
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X mov ax,memblk1st ; first mem blk
- X xor dx,dx ; largest size found
- X jmp gook
- Xgookloop:
- X mov ds,ax
- X test ds:memblkflg,MASK_used ; is this blk used?
- X jnz gookme ; yup
- X cmp ds:memblksiz,cx ; is it large enough?
- X jc gookme ; nope
- X mov dx,ds:memblksiz ; got one!
- X ret
- Xgookme:
- X mov ax,ds:memblknxt
- Xgook:
- X or ax,ax ; end of list?
- X jnz gookloop ; around and around
- X ret
- X
- Xlargestmem ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xkillmem PROC NEAR
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X test ds:memblkflg,MASK_used ; is it used?
- X jz memnotused ; don't kill ovl
- X push es
- X mov es,ds:memblkovl
- X and ovlflg,NOT MASK loaded ; zap ovl associated with this blk
- X and ovlflg,NOT MASK ems
- X pop es
- Xmemnotused:
- X jmp mergemem ; merge free memory
- X
- Xkillmem ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xkillovl PROC NEAR ; preserves bx
- X
- X ASSUME DS:ovltbl,ES:NOTHING
- X
- X mov ds,ax
- X and ovlflg,NOT MASK loaded ; ovl no longer loaded
- X test ovlflg,MASK ems ; was it in ems ?
- X jz noemskill
- X and ovlflg,NOT MASK ems ; no longer in ems
- X mov ax,ovlemshdl
- X call mappage
- Xnoemskill:
- X mov ax,ovlmemblk ; get mem blk
- X sub ax,MEMCTLBLKSIZ
- X mov ds,ax
- X jmp mergemem ; merge free memory
- X
- Xkillovl ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xmergemem PROC NEAR
- X
- X; merge physically adjacent free memory blocks. Preserves es. ds -> a free block.
- X
- X ASSUME DS:NOTHING,ES:NOTHING
- X
- X push dx
- X push es
- X and ds:memblkflg,NOT MASK_used ; set current free
- X mov ax,ds:memblkprv ; get previous blk
- X or ax,ax ; was there a previous blk?
- X jz gibber ; nope
- X mov es,ax
- X test es:memblkflg,MASK_used ; is the previous blk used?
- X jnz gibber ; yup
- X add ax,es:memblksiz ; end of previous blk
- X mov dx,ds
- X cmp dx,ax ; physically adjacent?
- X jnz gibber ; nope
- X mov ax,ds:memblksiz
- X add es:memblksiz,ax ; adjust size of new larger blk
- X mov ax,ds:memblknxt ; fix pointers
- X mov es:memblknxt,ax
- X or ax,ax
- X jz almostgibber
- X mov ds,ax ; fix pointer of next blk
- X mov ds:memblkprv,es
- Xalmostgibber:
- X mov ax,es
- X mov ds,ax ; new blk segment
- Xgibber:
- X mov ax,ds:memblknxt ; get next blk
- X or ax,ax ; was there a next blk?
- X jz killdone ; nope
- X mov es,ax
- X test es:memblkflg,MASK_used ; is the nxt blk used?
- X jnz killdone ; yup
- X mov ax,ds
- X add ax,ds:memblksiz ; end of this blk
- X mov dx,es
- X cmp ax,dx ; physically adjacent?
- X jnz killdone ; nope
- X mov ax,es:memblksiz
- X add ds:memblksiz,ax ; adjust size of new larger blk
- X mov ax,es:memblknxt ; fix pointers
- X mov ds:memblknxt,ax
- X or ax,ax
- X jz killdone
- X mov es,ax ; fix pointer of blk after nxt
- X mov es:memblkprv,ds
- Xkilldone:
- X and ds:memblkflg,NOT MASK_used ; make sure it's free
- X pop es
- X pop dx
- X mov ax,ds
- X ret
- X
- Xmergemem ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xgetmoreram PROC NEAR ; try to alloc remaining pieces
- X ; of memory if any
- X ASSUME DS:NOTHING,ES:NOTHING ; return dx = biggest block
- X
- X push cx
- X push bx
- X push si
- X push di
- X push ds
- X push es
- X xor dx,dx
- X mov ax,memblk1st
- Xnxtlowblk:
- X mov ds,ax
- X mov ax,ds:memblknxt
- X or ax,ax
- X jnz nxtlowblk
- X
- X mov si,OFFSET memblks ; a place to store the handles
- X mov di,OFFSET tempmem ; a place to store the rejects
- X mov cx,16 ; 16 more max
- Xgetramlp:
- X mov ah,DOSALLOC
- X mov bx,0ffffh ; Everything
- X int DOS
- X cmp bx,10h ; nothing smaller than .25k please
- X jc gotallram
- X mov ah,DOSALLOC ; allocate our own memory
- X int DOS
- X jc gotallram ; oops!
- X cmp ax,ovltblbse ; is it after our first mem blk?
- X jc releaseblk
- X cmp dx,bx
- X jnc notbigger
- X mov dx,bx
- Xnotbigger:
- X mov cs:[si],ax ; save it
- X mov es,ax
- X mov es:memblkflg,0 ; clear mem flags
- X mov es:memblknxt,0 ; set next to nothing
- X mov es:memblkovl,0 ; no overlays loaded
- X mov es:memblkprv,ds ; point to previous
- X mov es:memblksiz,bx ; allocated memory block size
- X mov ds:memblknxt,es ; point to next
- X add si,2
- X mov ds,ax
- X jmp short getnxtram
- Xreleaseblk:
- X mov cs:[di],ax
- X add di,2
- Xgetnxtram:
- X loop getramlp
- Xgotallram:
- X mov si,OFFSET tempmem
- X mov cx,16
- Xreleaselp:
- X mov ax,cs:[si]
- X cmp ax,-1
- X jz relnext
- X mov es,ax
- X mov ah,DOSFREE
- X int DOS
- X mov WORD PTR cs:[si],-1
- Xrelnext:
- X add si,2
- X loop releaselp
- X pop es
- X pop ds
- X pop di
- X pop si
- X pop bx
- X pop cx
- X ret
- X
- Xgetmoreram ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xgetemsmem PROC NEAR
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X xor dx,dx ; no ems memory
- X cmp emmflg,-1
- X jz testemsslots
- X ret
- Xtestemsslots:
- X mov curemshandle,-1
- X mov di,OFFSET emsmemblks
- X mov bx,cx
- X mov cx,16
- Xemsfreeslot:
- X mov ax,cs:[di]
- X cmp ax, -1
- X jz gotemsslot
- X call mappage
- X cmp ax,bx
- X jnc foundpage
- X add di,2
- X loop emsfreeslot
- X mov cx,bx
- X xor dx,dx
- X ret
- Xgotemsslot:
- X mov cx,bx
- X mov bx,4
- X mov ah,EMMALLOC
- X push cx ; paranoia ! shouldn't be necessary.
- X push di
- X push es
- X int EMM
- X pop es
- X pop di
- X pop cx
- X or ah,ah
- X jz gotsomeems
- X xor dx,dx
- X ret
- Xgotsomeems:
- X mov cs:[di],dx
- X mov ovlemshdl,dx
- X or ovlflg,MASK ems
- X mov ax,dx
- X call mapemspages
- X mov ax,emsframe
- X mov ds,ax
- X mov ds:memblkflg,0 ; clear mem flags
- X mov ds:memblknxt,0 ; set next to nothing
- X mov ds:memblkprv,0 ; set previous to nothing
- X mov ds:memblkovl,0 ; no overlay loaded
- X mov dx,1000h
- X mov ds:memblksiz,dx
- X ret
- X
- Xfoundpage:
- X mov cx,bx
- X mov ds,si
- X mov dx,ax
- X mov ax,cs:[di]
- X mov ovlemshdl,ax
- X or ovlflg,MASK ems
- X ret
- X
- Xgetemsmem ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xmappage PROC NEAR ; map a 64K block of EMS mem.
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X cmp ax,curemshandle
- X jnz doems
- X ret
- Xdoems:
- X push bx
- X push dx
- X push ds
- X push es
- X call mapemspages
- X mov ax,emsframe
- X xor dx,dx
- X xor si,si
- Xemsset:
- X mov ds,ax
- X test ds:memblkflg,MASK_used ; mem blk used ?
- X jz emsfreeblk
- X mov es,ds:memblkovl
- X or ovlflg,MASK ems OR MASK loaded
- X jmp emsnext
- Xemsfreeblk:
- X mov ax,ds:memblksiz
- X cmp dx,ax
- X jnc emsnext
- X mov dx,ax
- X mov si,ds
- Xemsnext:
- X mov ax,ds:memblknxt
- X or ax,ax
- X jnz emsset
- X
- X mov ax,dx
- X pop es
- X pop ds
- X pop dx
- X pop bx
- X ret
- X
- Xmappage ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xmapemspages PROC NEAR
- X
- X ASSUME DS:NOTHING,ES:ovltbl
- X
- X push es
- X push bx
- X push cx
- X push dx
- X mov curemshandle,ax
- X mov dx,ax
- X mov ah,EMMMAP
- X xor al,al ; physical page 0
- X xor bx,bx ; logical page 0
- X push dx
- X int EMM
- X pop dx
- X or ah,ah
- X jnz emmerror
- X mov ah,EMMMAP
- X mov al,1 ; physical page 1
- X mov bx,1 ; logical page 1
- X push dx
- X int EMM
- X pop dx
- X or ah,ah
- X jnz emmerror
- X mov ah,EMMMAP
- X mov al,2 ; physical page 2
- X mov bx,2 ; logical page 2
- X push dx
- X int EMM
- X pop dx
- X or ah,ah
- X jnz emmerror
- X mov ah,EMMMAP
- X mov al,3 ; physical page 3
- X mov bx,3 ; logical page 3
- X int EMM
- X or ah,ah
- X jnz emmerror
- X mov es,ovltblbse
- X mov cx,ovlcnt
- X xor bx,bx
- Xtestems:
- X test ovlflg[bx],MASK ems
- X jz nxttestems
- X and ovlflg[bx],NOT MASK loaded
- Xnxttestems:
- X add bx,OVLSEGSIZ
- X loop testems
- X pop dx
- X pop cx
- X pop bx
- X pop es
- X ret
- X
- Xemmerror:
- X mov al,EMSERR ; ems manager error
- X jmp putserr
- X
- Xmapemspages ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xgethdr PROC NEAR ; read EXE header from handle
- X
- X ASSUME DS:NOTHING,ES:NOTHING
- X
- X mov dx,OFFSET hdr ; a place to put it
- X mov bx,si
- X shl bx,1
- X mov bx,ovlfilhdl[bx] ; the file handle
- Xreadagain:
- X mov cx,TYPE EXEHDR ; header size in bytes
- X mov ah,DOSREAD
- X int DOS ; read from file
- X jc exegone ; oops?
- X cmp ax,cx ; got correct number of bytes?
- X je gothdr
- XIFNDEF NOSPLIT
- X cmp ax,0 ; Anything?
- X je gotonxtfil
- XENDIF
- X jmp exerotten
- XIFNDEF NOSPLIT
- Xgotonxtfil:
- X inc si
- X cmp si,MAXFILES+1
- X je exegone ; We're out of files!
- X mov bx,si
- X shl bx,1
- X cmp ovlfilhdl[bx],-1 ; Any more files?
- X je gotonxtfil ; not here.
- X
- X mov bx,ovlfilhdl[bx] ; Slide in new handle
- X xor bp,bp ; reset file offset
- X jmp readagain
- XENDIF
- Xgothdr:
- X cmp hdr.exesign,EXESIGNUM ; sanity check
- X jne exerotten
- X
- X ret ; Wow, it worked!
- Xexegone:
- X mov al,NOHDRERR ; missing overlays!
- X jmp putserr ; You lose!
- XIFNDEF NOSPLIT
- Xexerotten:
- X mov al,HDRERR ; corruption!
- X jmp putserr ; You lose!
- XENDIF
- X
- Xgethdr ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xopenfiles PROC NEAR ; Find our cohorts in crime
- X
- X push es
- XIFNDEF NOSPLIT
- X mov ah,DOSGETDTA ; Pick up DTA
- X int DOS ; and
- X mov dtaseg,es ; store
- X mov dtaoffset,bx ; it
- X
- X push ds
- X mov dx,OFFSET ovldta ; Set new DTA for file search
- X mov ax,cs
- X mov ds,ax ; point to the right seg
- X mov ah,DOSSETDTA
- X int DOS
- X pop ds ; set this back for upcoming lodsb
- XENDIF
- X mov cx,MAXNAMESIZE/2
- X mov bx,cs
- X mov es,bx
- X mov di, OFFSET filestring
- X
- X rep movsw ; load path from si to di
- XIFNDEF NOSPLIT
- X mov di, OFFSET filestring
- X mov al,0
- X mov cx,MAXNAMESIZE
- X cld
- X repne scasb ; search null for end of string
- X
- X sub cx,MAXNAMESIZE
- X neg cx
- X mov bx,cx
- X
- X cmp cx,MAXNAMESIZE
- X je checkslash
- X
- X dec bx ; keep string length
- X dec di ; cause were past null now
- X
- X cmp bx,7
- X jle patherr ; "C:\.EXE" = 7
- Xcheckslash:
- X mov ax,DOSGETSWITCH ; divine switchar
- X int DOS ; it influences the path
- X
- X mov al,'\' ; if swichar = '/' pathsep = '\'
- X cmp dl,'/'
- X je searchslash
- X mov al,'/' ; else pathsep = '/'
- Xsearchslash:
- X std
- X repne scasb ; search back for '\'
- X cld
- X
- X mov dx,bx
- X sub dx,cx ; keep file name length
- X dec dx
- X
- X mov cx,0 ; reset for upcoming loop
- X mov pathlen,bx ; hold these for recall
- X mov namelen,dx
- X cmp dx,12 ; "LONGNAME.EXE" = 12
- X jle openroot ; Path name too long?
- Xpatherr:
- X mov al,NAMERR ; real problems here.
- X jmp putserr
- Xopenroot:
- XENDIF
- X mov ax,cs
- X mov ds,ax ; set ds to code
- X
- X mov dx, OFFSET filestring ; open root code
- X mov al,0 ; access code
- X mov ah,DOSOPEN
- X int DOS ; open sez me
- X jnc dontdie
- X
- X mov al,FILEERR ; can't open root
- X jmp putserr
- Xdontdie:
- X mov ovlfilhdl[0],ax ; save handle in array
- XIFNDEF NOSPLIT
- X cmp namelen,11 ; Max sized exe name (8.3)?
- X jg bigfilename ; if not
- X inc pathlen ; add one to path length
- X inc namelen
- Xbigfilename:
- X mov di,OFFSET filestring ; es is still code
- X add di,pathlen
- X sub di,5 ; append
- X mov si,OFFSET ovlext ; wildcard extension
- X mov cx,6 ; and null
- X rep movsb ; to filestring
- X
- X mov cx,0 ; Match "normal" files
- X mov dx,OFFSET filestring
- X mov ah,DOSSEARCH
- X int DOS ; Set DTA with Wildcard.
- X jc aok ; Not a single match
- X mov cx,MAXFILES ; set upcoming loop
- X mov dx,namelen
- X sub pathlen,dx ; shorten absolute path
- Xopenloop:
- X push cx
- X mov bx,pathlen
- X mov di,OFFSET filestring ; es is still in code
- X add di,bx
- X mov si,OFFSET ovldta.file_name
- X mov cx,namelen ; since this *should* be
- X rep movsb
- X pop cx
- X
- X mov dx,OFFSET filestring ; path to overlay file
- X mov al,0 ; access code
- X mov ah,DOSOPEN
- X int DOS ; open overlay file
- X jnc dontdie2
- Xfileopenerr:
- X call itoa
- X
- X mov al,OVLERR ; can't open file!
- X jmp putserr
- Xdontdie2:
- X mov bx,cx ; put file number in bx
- X shl bx,1 ; 2 * bx for array index
- X mov ovlfilhdl[bx],ax ; save handle in array
- X
- X mov ah,DOSNEXTFILE ; Look for more files
- X int DOS
- X jc aok
- X
- X loop openloop ; open only 15 overlays
- Xaok:
- X mov dx,dtaoffset ; Time to unset DTA
- X mov ds,dtaseg
- X mov ah,DOSSETDTA
- X int DOS
- XENDIF
- X pop es
- X
- X ret
- X
- Xopenfiles ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xputserr PROC NEAR
- X
- X; display error msg, close file, restore int vectors, free mem and return to DOS.
- X
- X ASSUME DS:NOTHING,ES:NOTHING
- X
- X xor ah,ah
- X push ax ; keep return code for later
- X push cs
- X pop ds
- X mov bx,ax
- X shl bx,1
- X add bx,OFFSET errortbl
- X mov dx,[bx]
- X cmp dx,-1
- X jz freeints
- X push dx
- X mov dx,OFFSET msghead
- X mov ah,PRINT
- X int DOS
- X pop dx
- X mov ah,PRINT
- X int DOS ; display error msg
- X
- X mov ah,PRINT
- X mov dx,OFFSET diag
- X int DOS
- X pop ax
- X push ax
- X call itoa ; error number
- X mov ah,DOSPUTC
- X mov dl,':'
- X int DOS
- X mov ax,VERSION
- X call itoa ; version number
- X mov ah,DOSPUTC
- X mov dl,':'
- X int DOS
- X mov ax,0a000h
- X sub ax,ovltblbse ; conventional memory
- X call itoa
- X mov ah,DOSPUTC
- X mov dl,':'
- X int DOS
- X mov si,OFFSET emsmemblks
- X mov cx,16
- X xor ax,ax
- Xemstotlp:
- X cmp WORD PTR cs:[si],-1
- X jz gotemstot
- X add ax,emmframesiz
- X add si,2
- X loop emstotlp
- Xgotemstot:
- X call itoa ; ems usage in blocks
- X mov ah,DOSPUTC
- X mov dl,')'
- X int DOS
- X
- X mov dx,OFFSET msgtail
- X mov ah,PRINT
- X int DOS
- Xfreeints:
- X call rstvectors ; restore all int vectors
- X
- X mov ax,ovltblbse
- X cmp ax,-1
- X jz freememblks
- X mov es,ax
- X mov ah,DOSFREE
- X int DOS
- Xfreememblks:
- X mov cx,16 ; do all allocated mem blocks
- X mov si,OFFSET memblks
- Xfreememlp:
- X mov ax,cs:[si] ; get memory blk segment
- X cmp ax,-1 ; was one ever allocated?
- X jz nxtmemlp ; nope
- X mov es,ax
- X mov ah,DOSFREE ; must free it.
- X int DOS
- Xnxtmemlp:
- X add si,2
- X loop freememlp
- X mov cx,16 ; do all allocated ems blocks
- X mov si,OFFSET emsmemblks
- Xfreeemsmemlp:
- X mov dx,cs:[si] ; get memory blk segment
- X cmp dx,-1 ; was one ever allocated?
- X jz nxtemsmemlp ; nope
- X mov ah,EMMFREE ; must free it.
- X int EMM
- Xnxtemsmemlp:
- X add si,2
- X loop freeemsmemlp
- Xclosefile:
- XIFNDEF NOSPLIT
- X mov cx,MAXFILES+1
- Xnextfile:
- X mov bx,cx
- X dec bx
- X shl bx,1
- X mov bx,ovlfilhdl[bx] ; get file handle
- XELSE
- X mov bx,ovlfilhdl[0]
- XENDIF
- X cmp bx,-1 ; was the file ever opened?
- X jz byebye ; nope
- X mov ah,DOSCLOSE ; close it
- X int DOS
- Xbyebye:
- XIFNDEF NOSPLIT
- X loop nextfile
- XENDIF
- X pop ax ; return code in al
- X mov ah,TERMINATE
- X int DOS ; terminate this process
- X
- Xputserr ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xitoa PROC NEAR
- X
- X push ax
- X xchg ah,al
- X call putbyte
- X pop ax
- X jmp putbyte
- X
- Xitoa ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xputbyte PROC NEAR
- X
- X push ax
- X shr al,1
- X shr al,1
- X shr al,1
- X shr al,1
- X call nibble
- X pop ax
- X jmp nibble
- X
- Xputbyte ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xnibble PROC NEAR
- X
- X push ax
- X and al,0fh
- X add al,30h
- X cmp al,3ah
- X jc nibok
- X add al,7
- Xnibok:
- X push dx
- X mov dl,al
- X mov ah,DOSPUTC
- X int DOS
- X pop dx
- X pop ax
- X ret
- X
- Xnibble ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xsetvectors PROC NEAR
- X
- X push ds
- X xor ax,ax
- X mov ds,ax
- X mov si,cs:intnum
- X cli
- X mov ax,[si]
- X mov WORD PTR cs:oldvec,ax ; save original vector
- X mov ax,[si+2]
- X mov WORD PTR cs:oldvec+2,ax
- X mov ax,OFFSET ovlmgr ; point to ovlmgr
- X mov [si],ax ; set int vector
- X mov [si+2],cs
- X
- X mov si,DOS*4
- X mov ax,[si]
- X mov WORD PTR cs:oldint21,ax ; save original vector
- X mov ax,[si+2]
- X mov WORD PTR cs:oldint21+2,ax
- X mov ax,OFFSET int21 ; point to new int21
- X mov [si],ax ; set int vector
- X mov [si+2],cs
- X sti
- X pop ds
- X ret
- X
- Xsetvectors ENDP
- X
- X;-------------------------------------------------------------------------------
- X
- Xrstvectors PROC NEAR
- X
- X push ds
- X xor ax,ax
- X mov ds,ax
- X mov si,DOS*4
- X cli
- X mov ax,WORD PTR cs:oldint21 ; put back dos vector
- X cmp ax,-1
- X jz rstvec
- X mov [si],ax
- X mov ax,WORD PTR cs:oldint21+2
- X mov [si+2],ax
- Xrstvec:
- X mov si,cs:intnum
- X mov ax,WORD PTR cs:oldvec ; put back ovlmgr vector
- X cmp ax,-1
- X jz rstdone
- X mov [si],ax
- X mov ax,WORD PTR cs:oldvec+2
- X mov [si+2],ax
- X sti
- Xrstdone:
- X pop ds
- X ret
- X
- Xrstvectors ENDP
- X
- Xcode ENDS
- X
- X END
- END_OF_FILE
- if test 46506 -ne `wc -c <'sys/msdos/ovlmgr.asm'`; then
- echo shar: \"'sys/msdos/ovlmgr.asm'\" unpacked with wrong size!
- fi
- # end of 'sys/msdos/ovlmgr.asm'
- fi
- echo shar: End of archive 18 \(of 108\).
- cp /dev/null ark18isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
- 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
- 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
- 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
- 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
- 101 102 103 104 105 106 107 108 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 108 archives.
- echo "Now execute 'rebuild.sh'"
- rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-