home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / sources / games / 326 < prev    next >
Encoding:
Internet Message Format  |  1993-01-28  |  58.8 KB

  1. Path: sparky!uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i018:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part18/108
  5. Message-ID: <4301@master.CNA.TEK.COM>
  6. Date: 28 Jan 93 19:14:22 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2518
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  12. Posting-number: Volume 16, Issue 18
  13. Archive-name: nethack31/Part18
  14. Supersedes: nethack3p9: Volume 10, Issue 46-102
  15. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  16.  
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 18 (of 108)."
  26. # Contents:  src/worn.c sys/msdos/ovlmgr.asm
  27. # Wrapped by billr@saab on Wed Jan 27 16:08:52 1993
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'src/worn.c' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'src/worn.c'\"
  31. else
  32. echo shar: Extracting \"'src/worn.c'\" \(8567 characters\)
  33. sed "s/^X//" >'src/worn.c' <<'END_OF_FILE'
  34. X/*    SCCS Id: @(#)worn.c    3.1    92/12/13
  35. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  36. X/* NetHack may be freely redistributed.  See license for details. */
  37. X
  38. X#include "hack.h"
  39. X
  40. Xstatic void FDECL(rel_1_obj, (struct monst *,struct obj *));
  41. X
  42. Xconst struct worn {
  43. X    long w_mask;
  44. X    struct obj **w_obj;
  45. X} worn[] = {
  46. X    { W_ARM, &uarm },
  47. X    { W_ARMC, &uarmc },
  48. X    { W_ARMH, &uarmh },
  49. X    { W_ARMS, &uarms },
  50. X    { W_ARMG, &uarmg },
  51. X    { W_ARMF, &uarmf },
  52. X#ifdef TOURIST
  53. X    { W_ARMU, &uarmu },
  54. X#endif
  55. X    { W_RINGL, &uleft },
  56. X    { W_RINGR, &uright },
  57. X    { W_WEP, &uwep },
  58. X    { W_AMUL, &uamul },
  59. X    { W_TOOL, &ublindf },
  60. X    { W_BALL, &uball },
  61. X    { W_CHAIN, &uchain },
  62. X    { 0, 0 }
  63. X};
  64. X
  65. Xvoid
  66. Xsetworn(obj, mask)
  67. Xregister struct obj *obj;
  68. Xlong mask;
  69. X{
  70. X    register const struct worn *wp;
  71. X    register struct obj *oobj;
  72. X
  73. X    for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) {
  74. X        oobj = *(wp->w_obj);
  75. X        if(oobj && !(oobj->owornmask & wp->w_mask))
  76. X            impossible("Setworn: mask = %ld.", wp->w_mask);
  77. X        if(oobj) {
  78. X            oobj->owornmask &= ~wp->w_mask;
  79. X            /* leave as "x = x <op> y", here and below, for broken
  80. X             * compilers */
  81. X            u.uprops[objects[oobj->otyp].oc_oprop].p_flgs = 
  82. X                u.uprops[objects[oobj->otyp].oc_oprop].p_flgs & 
  83. X                ~wp->w_mask;
  84. X            if (oobj->oartifact) set_artifact_intrinsic(oobj, 0, mask);
  85. X        }
  86. X        *(wp->w_obj) = obj;
  87. X        if(obj) {
  88. X            obj->owornmask |= wp->w_mask;
  89. X        /* prevent getting intrinsics from wielding potions, etc... */
  90. X        /* wp_mask should be same as mask at this point */
  91. X            if(obj->oclass == WEAPON_CLASS || mask != W_WEP) {
  92. X            u.uprops[objects[obj->otyp].oc_oprop].p_flgs = 
  93. X                u.uprops[objects[obj->otyp].oc_oprop].p_flgs | 
  94. X                wp->w_mask;
  95. X            if (obj->oartifact) set_artifact_intrinsic(obj,1,mask);
  96. X            } else if(obj->oartifact)
  97. X            set_artifact_intrinsic(obj,1,mask);
  98. X        }
  99. X    }
  100. X}
  101. X
  102. X/* called e.g. when obj is destroyed */
  103. Xvoid
  104. Xsetnotworn(obj)
  105. Xregister struct obj *obj;
  106. X{
  107. X    register const struct worn *wp;
  108. X
  109. X    if (!obj) return;
  110. X    for(wp = worn; wp->w_mask; wp++)
  111. X        if(obj == *(wp->w_obj)) {
  112. X            *(wp->w_obj) = 0;
  113. X            u.uprops[objects[obj->otyp].oc_oprop].p_flgs = 
  114. X                u.uprops[objects[obj->otyp].oc_oprop].p_flgs & 
  115. X                    ~wp->w_mask;
  116. X            obj->owornmask &= ~wp->w_mask;
  117. X            if (obj->oartifact)
  118. X                set_artifact_intrinsic(obj, 0, wp->w_mask);
  119. X        }
  120. X}
  121. X
  122. X#ifdef MUSE
  123. Xint
  124. Xfind_mac(mon)
  125. Xregister struct monst *mon;
  126. X{
  127. X    register struct obj *obj;
  128. X    int base = mon->data->ac;
  129. X    long mwflags = mon->misc_worn_check;
  130. X
  131. X    for(obj = mon->minvent; obj; obj = obj->nobj) {
  132. X        if (obj->owornmask & mwflags)
  133. X            base -= ARM_BONUS(obj);
  134. X    }
  135. X    return base;
  136. X}
  137. X
  138. X/* Wear first object of that type it finds, and never switch unless it
  139. X * has none at all.  This means that monsters with leather armor never
  140. X * switch to plate mail, but it also avoids the overhead of having seven
  141. X * struct obj *s for every monster in the game, more if we ever extend this.
  142. X */
  143. Xvoid
  144. Xm_dowear(mon, creation)
  145. Xregister struct monst *mon;
  146. Xboolean creation;
  147. X{
  148. X    register struct obj *obj;
  149. X
  150. X    /* Note the restrictions here are the same as in dowear in do_wear.c
  151. X     * except for the additional restriction on intelligence.  (Players
  152. X     * are always intelligent, even if polymorphed).
  153. X     */
  154. X    if (verysmall(mon->data) || nohands(mon->data)) return;
  155. X    if (is_animal(mon->data) || mindless(mon->data)) return;
  156. X
  157. X    for(obj = mon->minvent; obj; obj = obj->nobj) {
  158. X        long flag;
  159. X
  160. X# ifdef TOURIST
  161. X        if (obj->otyp == HAWAIIAN_SHIRT) flag = W_ARMU;
  162. X        else
  163. X# endif
  164. X        if (is_cloak(obj)) flag = W_ARMC;
  165. X        else if (is_helmet(obj)) flag = W_ARMH;
  166. X        else if (is_shield(obj)) {
  167. X            if (MON_WEP(mon) && bimanual(MON_WEP(mon)))
  168. X                continue;
  169. X            flag = W_ARMS;
  170. X        } else if (is_gloves(obj)) {
  171. X            if (MON_WEP(mon) && MON_WEP(mon)->cursed)
  172. X                continue;
  173. X            flag = W_ARMG;
  174. X        } else if (is_boots(obj)) flag = W_ARMF;
  175. X        else if (obj->oclass == ARMOR_CLASS) {
  176. X#ifdef POLYSELF
  177. X            if (cantweararm(mon->data))
  178. X                continue;
  179. X#endif
  180. X            flag = W_ARM;
  181. X        } else continue;
  182. X        if (mon->misc_worn_check & flag) continue;
  183. X            /* already wearing one */
  184. X        if (!creation && canseemon(mon)) {
  185. X            pline("%s puts on %s.", Monnam(mon),
  186. X                        distant_name(obj, doname));
  187. X            mon->mfrozen = objects[obj->otyp].oc_delay;
  188. X            if (mon->mfrozen) mon->mcanmove = 0;
  189. X        }
  190. X        mon->misc_worn_check |= flag;
  191. X        obj->owornmask |= flag;
  192. X    }
  193. X}
  194. X
  195. Xstruct obj *
  196. Xwhich_armor(mon, flag)
  197. Xstruct monst *mon;
  198. Xlong flag;
  199. X{
  200. X    register struct obj *obj;
  201. X
  202. X    for(obj = mon->minvent; obj; obj = obj->nobj)
  203. X        if (obj->owornmask & flag) return obj;
  204. X    return((struct obj *)0);
  205. X}
  206. X
  207. Xstatic void
  208. Xrel_1_obj(mon, obj)
  209. Xstruct monst *mon;
  210. Xstruct obj *obj;
  211. X{
  212. X    struct obj *otmp;
  213. X    struct obj *backobj = (struct obj *)0;
  214. X
  215. X    for(otmp = mon->minvent; otmp; otmp = otmp->nobj) {
  216. X        if (obj == otmp) {
  217. X            if (!backobj) mon->minvent = otmp->nobj;
  218. X            else backobj->nobj = otmp->nobj;
  219. X            place_object(otmp, mon->mx, mon->my);
  220. X            otmp->nobj = fobj;
  221. X            fobj = otmp;
  222. X            if (cansee(mon->mx, mon->my)) newsym(mon->mx, mon->my);
  223. X            return;
  224. X        }
  225. X        backobj = otmp;
  226. X    }
  227. X    impossible("%s has %s missing?", Monnam(mon), xname(obj));
  228. X}
  229. X
  230. Xvoid
  231. Xmon_break_armor(mon)
  232. Xstruct monst *mon;
  233. X{
  234. X    register struct obj *otmp;
  235. X    struct permonst *mdat = mon->data;
  236. X    boolean vis = cansee(mon->mx, mon->my);
  237. X    const char *pronoun, *ppronoun;
  238. X
  239. X    switch(gender(mon)) {
  240. X        case 0: pronoun = "him"; ppronoun = "his"; break;
  241. X        case 1: pronoun = ppronoun = "her"; break;
  242. X        default: pronoun = "it"; ppronoun = "its"; break;
  243. X    }
  244. X    if (breakarm(mdat)) {
  245. X        if (otmp = which_armor(mon, W_ARM)) {
  246. X        if (vis)
  247. X            pline("%s breaks out of %s armor!", Monnam(mon), ppronoun);
  248. X        else
  249. X            You("hear a cracking sound.");
  250. X        mon->misc_worn_check &= ~W_ARM;
  251. X        m_useup(mon, otmp);
  252. X        }
  253. X        if (otmp = which_armor(mon, W_ARMC)) {
  254. X        if (otmp->oartifact) {
  255. X            if (vis)
  256. X            pline("%s cloak falls off!", s_suffix(Monnam(mon)));
  257. X            mon->misc_worn_check &= ~W_ARMC;
  258. X            otmp->owornmask &= ~W_ARMC;
  259. X            rel_1_obj(mon, otmp);
  260. X        } else {
  261. X            if (vis)
  262. X            pline("%s cloak tears apart!", s_suffix(Monnam(mon)));
  263. X            else
  264. X            You("hear a ripping sound.");
  265. X            mon->misc_worn_check &= ~W_ARMC;
  266. X            m_useup(mon, otmp);
  267. X        }
  268. X        }
  269. X# ifdef TOURIST
  270. X        if (otmp = which_armor(mon, W_ARMU)) {
  271. X        if (vis)
  272. X            pline("%s shirt rips to shreds!", s_suffix(Monnam(mon)));
  273. X        else
  274. X            You("hear a ripping sound.");
  275. X        mon->misc_worn_check &= ~W_ARMU;
  276. X        m_useup(mon, otmp);
  277. X        }
  278. X# endif
  279. X        } else if (sliparm(mdat)) {
  280. X        if (otmp = which_armor(mon, W_ARM)) {
  281. X        if (vis)
  282. X            pline("%s armor falls around %s!", 
  283. X                     s_suffix(Monnam(mon)), pronoun);
  284. X        else
  285. X            You("hear a thud.");
  286. X        mon->misc_worn_check &= ~W_ARM;
  287. X        otmp->owornmask &= ~W_ARM;
  288. X        rel_1_obj(mon, otmp);
  289. X        }
  290. X        if (otmp = which_armor(mon, W_ARMC)) {
  291. X        if (vis)
  292. X            if (is_whirly(mon->data))
  293. X            pline("%s cloak falls, unsupported!", 
  294. X                         s_suffix(Monnam(mon)));
  295. X            else
  296. X            pline("%s shrinks out of %s cloak!", Monnam(mon),
  297. X                                ppronoun);
  298. X        mon->misc_worn_check &= ~W_ARMC;
  299. X        otmp->owornmask &= ~W_ARMC;
  300. X        rel_1_obj(mon, otmp);
  301. X        }
  302. X# ifdef TOURIST
  303. X        if (otmp = which_armor(mon, W_ARMU)) {
  304. X        if (vis)
  305. X            if (sliparm(mon->data))
  306. X            pline("%s seeps right through %s shirt!",
  307. X                    Monnam(mon), ppronoun);
  308. X            else
  309. X            pline("%s becomes much too small for %s shirt!",
  310. X                    Monnam(mon), ppronoun);
  311. X        mon->misc_worn_check &= ~W_ARMU;
  312. X        otmp->owornmask &= ~W_ARMU;
  313. X        rel_1_obj(mon, otmp);
  314. X        }
  315. X# endif
  316. X    }
  317. X    if (nohands(mdat) || verysmall(mdat)) {
  318. X        if (otmp = which_armor(mon, W_ARMG)) {
  319. X        if (vis)
  320. X            pline("%s drops %s gloves%s!", Monnam(mon), ppronoun,
  321. X                    MON_WEP(mon) ? " and weapon" : "");
  322. X        possibly_unwield(mon);
  323. X        mon->misc_worn_check &= ~W_ARMG;
  324. X        otmp->owornmask &= ~W_ARMG;
  325. X        rel_1_obj(mon, otmp);
  326. X        }
  327. X        if (otmp = which_armor(mon, W_ARMS)) {
  328. X        if (vis)
  329. X            pline("%s can no longer hold %s shield!", Monnam(mon),
  330. X                                ppronoun);
  331. X        else
  332. X            You("hear a clank.");
  333. X        mon->misc_worn_check &= ~W_ARMS;
  334. X        otmp->owornmask &= ~W_ARMS;
  335. X        rel_1_obj(mon, otmp);
  336. X        }
  337. X        if (otmp = which_armor(mon, W_ARMH)) {
  338. X        if (vis)
  339. X            pline("%s helmet falls to the floor!", 
  340. X                       s_suffix(Monnam(mon)));
  341. X        else
  342. X            You("hear a clank.");
  343. X        mon->misc_worn_check &= ~W_ARMH;
  344. X        otmp->owornmask &= ~W_ARMH;
  345. X        rel_1_obj(mon, otmp);
  346. X        }
  347. X        if (otmp = which_armor(mon, W_ARMF)) {
  348. X        if (vis) {
  349. X            if (is_whirly(mon->data))
  350. X            pline("%s boots fall away!", 
  351. X                           s_suffix(Monnam(mon)));
  352. X            else pline("%s boots %s off %s feet!", 
  353. X            s_suffix(Monnam(mon)),
  354. X            verysmall(mdat) ? "slide" : "are pushed", ppronoun);
  355. X        }
  356. X        mon->misc_worn_check &= ~W_ARMF;
  357. X        otmp->owornmask &= ~W_ARMF;
  358. X        rel_1_obj(mon, otmp);
  359. X        }
  360. X    }
  361. X}
  362. X#endif
  363. X
  364. X/*worn.c*/
  365. END_OF_FILE
  366. if test 8567 -ne `wc -c <'src/worn.c'`; then
  367.     echo shar: \"'src/worn.c'\" unpacked with wrong size!
  368. fi
  369. # end of 'src/worn.c'
  370. fi
  371. if test -f 'sys/msdos/ovlmgr.asm' -a "${1}" != "-c" ; then 
  372.   echo shar: Will not clobber existing file \"'sys/msdos/ovlmgr.asm'\"
  373. else
  374. echo shar: Extracting \"'sys/msdos/ovlmgr.asm'\" \(46506 characters\)
  375. sed "s/^X//" >'sys/msdos/ovlmgr.asm' <<'END_OF_FILE'
  376. X;    SCCS Id: @(#)ovlmgr.asm         91/09/04
  377. X;  Copyright (c) 1989, 1990, 1991, 1992, 1993 Pierre Martineau and
  378. X;  Stephen Spackman.  All Rights Reserved.
  379. X;  This product may be freely redistributed.  See NetHack license for details.
  380. X
  381. XVERSION     EQU    3100h
  382. X
  383. X        PAGE    57,132
  384. X        TITLE    'DOS Overlay Manager for MSC 5.1+'
  385. X        SUBTTL    'Copyright (c) 1989, 1990, 1991, 1992, 1993 Pierre Martineau and Stephen Spackman. All Rights Reserved.'
  386. X
  387. X; Multiple overlay file support for v30a0 by Norm Meluch with some input from Stephen.
  388. X
  389. X; acknowledgements:   - Many thanks to Norm Meluch for his invaluable help
  390. X;              - No thanks to Microsoft
  391. X;              - alltrsidsctysti!!!
  392. X;              - izchak and friends for impetus
  393. X;              - us for brilliance
  394. X;              - coffee for speed
  395. X;              - others as necessary
  396. X
  397. X; assumptions:          - all registers are preserved including flags
  398. X;              - the stack is preserved
  399. X;              - re-entrancy is not required
  400. X
  401. X; options:          /Di386    use 80386-specific opcodes
  402. X;                (faster, but no good for weaker machines)
  403. X;              /DNOEMS    omit EMS support
  404. X;                (needed if application uses EMS)
  405. X;              /DNOSPLIT    omit support for external .OVL files
  406. X
  407. XDOSALLOC    EQU    48h            ; memory allocation
  408. XDOSFREE     EQU    49h            ; free allocated memory
  409. XDOSREALLOC    EQU    4ah            ; modify memory block
  410. XDOSREAD     EQU    3fh            ; read bytes from handle
  411. XDOSSEEK     EQU    42h            ; logical handle seek
  412. XDOSOPEN     EQU    3dh            ; open handle
  413. XDOSCLOSE    EQU    3eh            ; close handle
  414. XDOSSETDTA    EQU    1ah            ; Set Data transfer area
  415. XDOSGETDTA    EQU    2fh            ; Get Data transfer area
  416. XDOSSEARCH    EQU    4eh            ; Search for 1st file match
  417. XDOSNEXTFILE    EQU    4fh            ; Search for next file match
  418. XDOSEXEC     EQU    4bh            ; exec child process
  419. XDOSPUTC     EQU    02h            ; print a char
  420. XDOSVERSION    EQU    30h            ; get version number
  421. XDOSGETVEC    EQU    35h            ; get interrupt vector
  422. XDOSGETSWITCH    EQU    3700h            ; get DOS switchar
  423. XDOS        EQU    21h            ; Dos interrupt #
  424. XPRINT        EQU    09h            ; print string
  425. XTERMINATE    EQU    4ch            ; terminate process
  426. XEMM        EQU    67h            ; EMM handler int vector
  427. XEMMSTATUS    EQU    40h            ; get EMM status
  428. XEMMFRAME    EQU    41h            ; get EMM page frame
  429. XEMMTOTALS    EQU    42h            ; get EMM pages available
  430. XEMMALLOC    EQU    43h            ; allocate EMM pages
  431. XEMMMAP        EQU    44h            ; map EMM pages
  432. XEMMFREE     EQU    45h            ; free EMM pages
  433. XMAXNAMESIZE    EQU    50h            ; max path name size
  434. XMAXFILES    EQU    0Eh            ; max # of *.OVL files
  435. XEXESIGNUM    EQU    5a4dh            ; Exe header signature
  436. XCR        EQU    0dh
  437. XLF        EQU    0ah
  438. XESCAPE        EQU    1bh
  439. XBELL        EQU    07h
  440. XPARSIZ        EQU    10h            ; this is the size of a paragraph - this better not change!
  441. XFAERIE        EQU    00h            ; Used for dummy segment allocation
  442. X
  443. XNOERR        EQU    0
  444. XDOSERR        EQU    1
  445. XFILEERR     EQU    2
  446. XNOMEMERR    EQU    3
  447. XFILEIOERR    EQU    4
  448. XVICTIMERR    EQU    5
  449. XRELERR        EQU    6
  450. XEMSERR        EQU    7
  451. XHDRERR        EQU    8
  452. XNAMERR        EQU    9
  453. XOVLERR        EQU    10
  454. XNOHDRERR    EQU    11
  455. X
  456. X; The following EXTRNs are supplied by the linker
  457. X
  458. XEXTRN        $$OVLBASE:BYTE            ; segment of OVERLAY_AREA
  459. XEXTRN        $$MPGSNOVL:BYTE         ; ^ to module table
  460. XEXTRN        $$MPGSNBASE:WORD        ; ^ to module segment fixups
  461. XEXTRN        $$INTNO:BYTE            ; interrupt number to be used
  462. XEXTRN        $$COVL:WORD            ; number of physical overlays
  463. XEXTRN        $$CGSN:WORD            ; number of modules
  464. XEXTRN        $$MAIN:FAR            ; ^ to function main()
  465. X
  466. XPUBLIC        $$OVLINIT            ; Our entry point
  467. X                        ; called by the c startup code
  468. XIFDEF i386
  469. XOP32        MACRO                ; 32 bit operand override
  470. X        DB    066h
  471. X        ENDM
  472. X
  473. Xpusha        MACRO                ; push all registers
  474. X        DB    060h
  475. X        ENDM
  476. X
  477. Xpopa        MACRO                ; pop all registers
  478. X        DB    061h
  479. X        ENDM
  480. XENDIF
  481. X
  482. Xovlflgrec    RECORD    locked:1=0,ems:1=0,loaded:1=0,file:4=0,pad:1 ; overlay flags
  483. X        ; "file" is the overlay file this overlay is in; 0 is the .EXE
  484. X        ; itself. Otherwise, the numbers are arbitrary.
  485. X
  486. X; This is a dirty hack. What we need is a virtual segment that will be built
  487. X; by the (our) loader in multiple copies, one per overlay. Unfortunately, this
  488. X; doesn't seem to be a sensible idea in the minds of the folks at Microsoft.
  489. X; Declaring this segment AT will ensure that it never appears in the exefile,
  490. X; and ASSUME is dumb enough to be fooled.
  491. X;
  492. X; The reason we want to do this is also not-to-be-tried-at-home: it turns out
  493. X; that we can code a faster interrupt handler if we map overlay numbers to
  494. X; segment values. Normally we would consider this unacceptable programming
  495. X; practise because it is 86-mode specific, but the *need* for this entire
  496. X; programme is 86-mode specific, anyway.
  497. X
  498. Xpspseg        SEGMENT PARA AT FAERIE        ; dummy segment for psp
  499. X        ORG    2ch            ; ^ to segment of environmemt in psp
  500. Xpspenv        LABEL    WORD
  501. Xpspseg        ENDS
  502. X
  503. Xovltbl        SEGMENT PARA AT FAERIE        ; Dummy segment definition for overlay table
  504. X
  505. X; NOTE: This segment definition MUST be exactly 16 bytes long
  506. X
  507. Xovlflg        ovlflgrec    <0,0,0,0,0>     ; overlay flags
  508. Xovlinvcnt    DB    ?            ; invocation count
  509. Xovlmemblk    DW    ?            ; ^ to allocated memory block
  510. Xovllrudat    DD    ?            ; misc lru data (pseudo time stamp)
  511. Xovlemshdl    DW    ?            ; ovl ems memory handle
  512. Xovlfiloff    DW    ?            ; ovl file offset in pages (512 bytes)
  513. Xovlsiz        DW    ?            ; ovl size in paragraphs
  514. Xovlhdrsiz    DW    ?            ; hdr size in paragraphs
  515. X
  516. XIF1
  517. XIF        ($ - ovlflg) GT PARSIZ
  518. X        .ERR
  519. X        %OUT This segment MUST be no more than 16 bytes, REALLY!!!
  520. XENDIF
  521. XENDIF
  522. X
  523. XOVLSEGSIZ    EQU    PARSIZ            ; this had better be true!!! (16 bytes)
  524. X
  525. Xovltbl        ENDS
  526. X
  527. XDTASTRUC    STRUC                ; internal DTA for ovlmgr
  528. X        DB    21 DUP (0)
  529. Xfile_attr    DB    0
  530. Xfile_time    DW    0
  531. Xfile_date    DW    0
  532. Xfile_size    DD    0
  533. Xfile_name    DB    9 DUP (0)
  534. Xfile_ext    DB    3 DUP (0)
  535. Xdtapad        DB    86 DUP (0)        ; Pad to 128 bytes
  536. XDTASTRUC    ENDS
  537. X
  538. XEXEHDR        STRUC                ; structure of an EXE header
  539. Xexesign     DW    EXESIGNUM        ; signature
  540. Xexelstpgesiz    DW    ?            ; last page size (512 byte pages)
  541. Xexesiz        DW    ?            ; total pages (including partial last page)
  542. Xrelocitems    DW    ?            ; number of relocation entries
  543. Xhdrparas    DW    ?            ; number of paragraphs in the header
  544. Xminalloc    DW    ?            ; minimum paragraph allocation
  545. Xmaxalloc    DW    ?            ; maximum patagraph allocation
  546. Xexess        DW    ?            ; initial stack segment
  547. Xexesp        DW    ?            ; initial stack pointer
  548. Xexechksum    DW    ?            ; checksum
  549. Xexeip        DW    ?            ; initial instruction pointer
  550. Xexecs        DW    ?            ; initial code segment
  551. Xreloctbloff    DW    ?            ; offset from beginning of header to relocation table
  552. Xexeovlnum    DW    ?            ; overlay number
  553. XEXEHDR        ENDS
  554. X
  555. XMASK_used    EQU    1            ; memory block flag
  556. X
  557. XMEMCTLBLK    STRUC                ; memory block structure
  558. Xmemblkflg    DB    ?            ; flags
  559. Xmemblkpad1    DB    ?            ; go ahead, delete me!
  560. Xmemblknxt    DW    ?            ; ^ to next block
  561. Xmemblkprv    DW    ?            ; ^ to previous block
  562. Xmemblkovl    DW    ?            ; ^ to overlay occupying this block
  563. Xmemblksiz    DW    ?            ; size in paragraphs
  564. Xmemblkpad    DB    PARSIZ - memblkpad MOD PARSIZ DUP (?) ; pad to 16 bytes
  565. XMEMCTLBLK    ENDS
  566. X
  567. XMEMCTLBLKSIZ    EQU    TYPE MEMCTLBLK / PARSIZ ; should equal 1 paragraph
  568. X
  569. X;-------------------------------------------------------------------------------
  570. X
  571. Xcode        SEGMENT PUBLIC
  572. X
  573. X; NOTE: the following order is optimum for alignment purposes across the
  574. X;    entire INTEL 80x86 family of processors.
  575. X
  576. Xovltim        DD    ?            ; pseudo-lru time variable
  577. Xfarcall     DD    ?            ; internal trampoline.
  578. Xoldvec        DD    -1            ; saved interrupt vector
  579. Xoldint21    DD    -1            ; saved int 21 vector
  580. Xsireg        DW    ?            ; temp save area
  581. XIFDEF i386
  582. X        DW    ?            ; for esi
  583. XENDIF
  584. Xdsreg        DW    ?            ; temp save area
  585. Xssreg        DW    ?
  586. Xspreg        DW    ?
  587. Xovlfilhdl    DW    MAXFILES+1 DUP (-1)      ; always-open file handles for .EXE, .OVL
  588. Xovltblbse    DW    -1            ; segment of first overlay descriptor
  589. Xmemblks     DW    16 DUP (-1)        ; allocated memory blocks
  590. Xmemblk1st    DW    ?            ; first memory block
  591. Xemsmemblks    DW    16 DUP (-1)        ; ems allocated memory blocks (64K each)
  592. Xcuremshandle    DW    -1            ; currently mapped handle
  593. Xovlcnt        DW    ?            ; # overlays
  594. Xmodcnt        DW    ?            ; # of modules
  595. Xovlrootcode    DW    ?            ; logical segment of OVERLAY_AREA
  596. Xovldata     DW    ?            ; logical segment of OVERLAY_END
  597. Xpspadd        DW    ?            ; our psp address + 10h (for relocations)
  598. Xemsframe    DW    ?            ; EMM page frame segment
  599. Xmoduletbl    DD    256 DUP (?)        ; module lookup table (256 modules)
  600. Xcurovl        DW    OFFSET stkframe     ; ^ into stack frame
  601. Xstkframe    DW    256*3 DUP (?)        ; internal stack (256 ovls deep)
  602. Xtempmem     DW    16 DUP (-1)        ; temp mem block storage
  603. Xintnum        DW    ?            ; ovlmgr int number
  604. Xhdr        EXEHDR    <>            ; EXE header work area
  605. X        DB    512-TYPE EXEHDR DUP (?) ; exe hdr buffer for relocations
  606. XEXEHDRTMPSIZ    EQU    $ - hdr         ; size of temp reloc buffer
  607. Xfilestring    DB    MAXNAMESIZE DUP (0)    ; string space for file specs
  608. Xpathlen        DW    ?            ; path length of file spec
  609. Xnamelen        DW    ?            ; length of file names
  610. Xovldta        DTASTRUC <>            ; DTA for ovlmgr use
  611. Xdtaseg        DW    ?            ; DTA segment for program
  612. Xdtaoffset    DW    ?            ; DTA offset for program
  613. Xerrortbl    DW    -1            ; error message pointers
  614. X        DW    OFFSET baddos
  615. X        DW    OFFSET nofile
  616. X        DW    OFFSET noroom
  617. X        DW    OFFSET badio
  618. X        DW    OFFSET nocore
  619. X        DW    OFFSET nocore
  620. X        DW    OFFSET badems
  621. X        DW    OFFSET badhdr
  622. X        DW    OFFSET badnam
  623. X        DW    OFFSET noovl
  624. X        DW    OFFSET nohdr
  625. X        DW    OFFSET unknown
  626. X        DW    OFFSET unknown
  627. X        DW    OFFSET unknown
  628. X        DW    OFFSET unknown
  629. Xemmname     DB    "EMMXXXX0"              ; EMM device driver name
  630. Xemmtot        DW    0            ; total emm blocks free
  631. Xemmframesiz    DW    4            ; frame size in blocks
  632. Xemmflg        DB    0            ; EMM present flag
  633. X
  634. Xi386code    DB    '386 specific code enabled.',CR,LF,'$'
  635. Xmemavl        DB    'Conventional memory available: $'
  636. Xparagraphs    DB    'H paragraphs.',CR,LF,'$'
  637. Xemsavl        DB    'EMS memory available: $'
  638. Xpages        DB    'H 16K-pages.',CR,LF,'$'
  639. Xbaddos        DB    'Incorrect DOS version. Must be 3.00 or later.$'
  640. Xnofile        DB    'Inaccessible EXE file. Can',39,'t load overlays.$'
  641. Xnoroom        DB    'Not enough free memory left to run this program.$'
  642. Xbadio        DB    'File I/O error.$'
  643. Xnocore        DB    'Internal memory allocation failure.$'
  644. Xbadems        DB    'EMS memory manager error.$'
  645. Xbadhdr        DB    'Executable or overlay header missing or damaged.$'
  646. Xbadnam        DB    'Unable to resolve overlay file names.$'
  647. Xnoovl        DB    'Inaccessible OVL file. Can',39,'t load overlays.$'
  648. Xnohdr        DB    'Incomplete executable.  OVL files missing?$'
  649. Xunknown     DB    'Unknown error!$'
  650. Xmsghead     DB    ESCAPE,'[0m',ESCAPE,'[K',CR,LF,ESCAPE,'[K',ESCAPE,'[1mOVLMGR:',ESCAPE,'[0m $'
  651. Xdiag        DB    ESCAPE,'[K',CR,LF,ESCAPE,'[K','        ($'
  652. Xmsgtail     DB    ESCAPE,'[K',CR,LF,ESCAPE,'[K',BELL,'$'
  653. Xovlext        DB    '?.OVL',0
  654. X
  655. X;-------------------------------------------------------------------------------
  656. X
  657. X$$OVLINIT    PROC    FAR            ; Init entry point
  658. X
  659. X        ASSUME    CS:code,DS:pspseg,ES:NOTHING
  660. X
  661. X        push    ax
  662. X        push    bx
  663. X        push    cx
  664. X        push    dx
  665. X        push    si
  666. X        push    di
  667. X        push    bp
  668. X        push    ds
  669. X        push    es            ; save the world
  670. X
  671. X        cld
  672. X        mov    ax,ds            ; get our psp
  673. X        add    ax,10h
  674. X        mov    pspadd,ax        ; save it
  675. X        mov    ah,DOSVERSION
  676. X        int    DOS
  677. X        cmp    al,3            ; DOS 3.0 or later
  678. X        jnc    doenvthing
  679. X        mov    al,DOSERR        ; incorrect version of dos
  680. X        jmp    putserr
  681. Xdoenvthing:
  682. X        mov    ds,pspenv        ; get environment segment
  683. X        mov    si,-1
  684. Xenvloop:                    ; search for end of environment
  685. X        inc    si
  686. X        cmp    WORD PTR [si],0
  687. X        jnz    envloop
  688. X        add    si,4            ; point to EXE filename
  689. X
  690. X        call    openfiles        ; Search & open overlay files
  691. XIFNDEF NOEMS
  692. Xchkems:
  693. X        mov    ah,DOSGETVEC
  694. X        mov    al,EMM
  695. X        int    DOS
  696. X        mov    ax,cs
  697. X        mov    ds,ax
  698. X        mov    di,0ah
  699. X        mov    si,OFFSET emmname
  700. X        mov    cx,8
  701. X        repe    cmpsb
  702. X        mov    al,0
  703. X        jnz    setemmflg
  704. X        mov    al,-1
  705. Xsetemmflg:
  706. X        mov    emmflg,al
  707. X        jnz    noemshere
  708. X        mov    ah,EMMFRAME
  709. X        int    EMM
  710. X        mov    emsframe,bx
  711. X        mov    ah,EMMTOTALS
  712. X        int    EMM
  713. X        mov    emmtot,bx
  714. Xnoemshere:
  715. XENDIF
  716. X        mov    ax,SEG $$OVLBASE    ; OVERLAY_AREA segment
  717. X        mov    ovlrootcode,ax
  718. X        mov    ax,SEG $$COVL        ; segment of DGROUP
  719. X        mov    ds,ax
  720. X        mov    bx,$$CGSN        ; number of modules
  721. X        mov    modcnt,bx        ; save for later use
  722. X        mov    bx,$$COVL        ; number of physical overlays
  723. X        mov    ovlcnt,bx        ; save for later use
  724. X
  725. X; Now allocate memory
  726. X        mov    ah,DOSALLOC        ; bx contains # paras needed for ovltbl
  727. X        int    DOS
  728. X        jnc    gotovlram
  729. X        jmp    buyram
  730. Xgotovlram:
  731. X        mov    ovltblbse,ax        ; overlay descriptor table begins at start of memory block
  732. X
  733. X        mov    cx,ovlcnt
  734. Xzeromem:
  735. X        mov    es,ax
  736. X        mov    es:ovlflg,0        ; initialise ovl flags
  737. X        mov    es:ovlinvcnt,0        ; initialise invocation count
  738. X        mov    es:ovlmemblk,0
  739. X        mov    WORD PTR es:ovllrudat,0     ; initialise ovl lru
  740. X        mov    WORD PTR es:ovllrudat+2,0
  741. X        mov    es:ovlemshdl,-1
  742. X        mov    es:ovlfiloff,0        ; initialize file offset
  743. X        mov    es:ovlsiz,0        ; initialize overlay size
  744. X        mov    es:ovlhdrsiz,0
  745. X        inc    ax
  746. X        loop    zeromem        
  747. X
  748. X        mov    ax,cs
  749. X        mov    ds,ax
  750. XIFDEF DEBUG
  751. XIFDEF i386
  752. X        mov    ah,print
  753. X        mov    dx,OFFSET msghead
  754. X        int    DOS
  755. X        mov    ah,print
  756. X        mov    dx,OFFSET i386code
  757. X        int    DOS
  758. XENDIF
  759. X        mov    ah,print
  760. X        mov    dx,OFFSET msghead
  761. X        int    DOS
  762. X        mov    ah,print
  763. X        mov    dx,OFFSET memavl
  764. X        int    DOS
  765. X        mov    ax,0a000h
  766. X        sub    ax,ovltblbse
  767. X        call    itoa
  768. X        mov    ah,print
  769. X        mov    dx,OFFSET paragraphs
  770. X        int    DOS
  771. XIFNDEF NOEMS
  772. X        mov    ah,print
  773. X        mov    dx,OFFSET msghead
  774. X        int    DOS
  775. X        mov    ah,print
  776. X        mov    dx,OFFSET emsavl
  777. X        int    DOS
  778. X        mov    ax,emmtot
  779. X        call    itoa
  780. X        mov    ah,print
  781. X        mov    dx,OFFSET pages
  782. X        int    DOS
  783. XENDIF
  784. XENDIF
  785. X        ASSUME    ES:ovltbl
  786. X
  787. X        xor    bp,bp
  788. X        xor    di,di
  789. X        xor    si,si            ; file handle loop ctr
  790. Xfilsegtbllpp:                    ; initialise ovl table
  791. X        call    gethdr            ; get an EXE header
  792. X
  793. X        mov    ax,ovltblbse
  794. X        add    ax,hdr.exeovlnum
  795. X        mov    es,ax            ; ^ to ovl table entry
  796. XIFNDEF NOSPLIT
  797. X        mov    cx,si            ; set file # in ovlflg
  798. X        shl    cx,1
  799. X        mov    ovlflg,cl
  800. XENDIF
  801. X        mov    ax,hdr.exesiz
  802. X        shl    ax,1
  803. X        shl    ax,1
  804. X        shl    ax,1
  805. X        shl    ax,1
  806. X        shl    ax,1            ; * 32
  807. X        mov    dx,hdr.exelstpgesiz
  808. X        or    dx,dx
  809. X        jz    emptypage
  810. X        shr    dx,1
  811. X        shr    dx,1
  812. X        shr    dx,1
  813. X        shr    dx,1            ; / 16
  814. X        inc    dx
  815. X        sub    ax,20h
  816. X        add    ax,dx
  817. Xemptypage:
  818. X        sub    ax,hdr.hdrparas     ; actual size of code
  819. X        mov    ovlsiz,ax        ; overlay size in paragraphs
  820. X        cmp    hdr.exeovlnum,0     ; skip if ovl 0 (root code)
  821. X        jz    notlargest
  822. X        cmp    ax,di            ; find largest ovl
  823. X        jc    notlargest
  824. X        mov    di,ax
  825. Xnotlargest:
  826. X        mov    ax,hdr.hdrparas
  827. X        shl    ax,1
  828. X        shl    ax,1
  829. X        shl    ax,1
  830. X        shl    ax,1
  831. X        mov    ovlhdrsiz,ax        ; hdr size in bytes
  832. X        mov    ovlfiloff,bp        ; initialise ovl file offset
  833. X        add    bp,hdr.exesiz        ; ^ to next overlay
  834. X        mov    dx,bp
  835. X        mov    cl,dh
  836. X        mov    dh,dl
  837. X        xor    ch,ch
  838. X        xor    dl,dl
  839. X        shl    dx,1
  840. X        rcl    cx,1            ; cx:dx = bp * 512
  841. X        mov    al,0
  842. X        mov    ah,DOSSEEK        ; seek to next ovl
  843. X        int    DOS
  844. X
  845. X        mov    cx,ovlcnt        ; check if all overlays found
  846. X        mov    ax,ovltblbse
  847. X        dec    cx            ; ovlcnt includes root
  848. X        add    ax,cx
  849. Xovloop:
  850. X        mov    es,ax
  851. XIFNDEF NOSPLIT
  852. X        mov    bl,ovlflg
  853. X        and    bx,MASK file
  854. X
  855. X        cmp    bx,0            ; if file # is 0
  856. X        jne    again
  857. XENDIF
  858. X        cmp    ovlfiloff,0        ; and offset is 0
  859. X        jne    again
  860. X        jmp    filsegtbllpp        ; then we're still looking
  861. Xagain:
  862. X        dec    ax
  863. X        loop    ovloop
  864. X
  865. X        ASSUME    ES:nothing        ; prepare first memory block
  866. X
  867. X        mov    ax,ovlrootcode        ; OVERLAY_AREA segment
  868. X        mov    memblk1st,ax        ; save pointer to first mem block
  869. X        mov    es,ax
  870. X        mov    es:memblkflg,0        ; clear mem flags
  871. X        mov    es:memblknxt,0        ; set next to nothing
  872. X        mov    es:memblkprv,0        ; set previous to nothing
  873. X        mov    es:memblkovl,0        ; no overlay loaded
  874. X        mov    es:memblksiz,di     ; di contains OVERLAY_AREA size in paragraphs
  875. X        add    ax,di
  876. X        mov    ovldata,ax        ; end of OVERLAY_END
  877. X        push    di
  878. X        mov    es,ovltblbse        ; temporary
  879. X        call    getemsmem        ; see if any ems available
  880. X        mov    es:ovlemshdl,-1     ; fix these!
  881. X        and    es:ovlflg,NOT MASK ems
  882. X        push    dx
  883. X        call    getmoreram        ; see if there are any other pieces lying around
  884. X        pop    ax
  885. X        pop    di
  886. X        or    ax,ax            ; any ems?
  887. X        jnz    noramcheck
  888. X        inc    di
  889. X        cmp    dx,di
  890. X        jc    buyram
  891. Xnoramcheck:
  892. X        mov    WORD PTR ovltim,0    ; initialise global lru time stamp
  893. X        mov    WORD PTR ovltim+2,0
  894. X        mov    di,OFFSET stkframe
  895. X        mov    WORD PTR cs:[di],-1    ; initialise stack frame
  896. X        add    di,6
  897. X        mov    ax,ovltblbse
  898. X        mov    cs:[di],ax
  899. X        mov    curovl,di        ; initialise stack frame pointer
  900. X        mov    es,ax
  901. X        mov    es:ovlflg,MASK locked OR MASK loaded ; set flags on ovl 0
  902. X        jmp    short chgintvec
  903. Xbuyram:
  904. X        mov    al,NOMEMERR        ; free up some TSRs or something
  905. X        jmp    putserr
  906. Xchgintvec:
  907. X        mov    ax,SEG $$INTNO
  908. X        mov    ds,ax
  909. X        mov    al,$$INTNO        ; get int number to use
  910. X        xor    ah,ah
  911. X        shl    ax,1
  912. X        shl    ax,1
  913. X        mov    intnum,ax
  914. X        call    setvectors        ; set up interrupt vectors
  915. X        mov    cx,modcnt        ; module count
  916. X        mov    ax,SEG $$MPGSNBASE
  917. X        mov    es,ax
  918. X        mov    ax,cs
  919. X        mov    ds,ax
  920. X
  921. X        ASSUME    DS:code
  922. X
  923. X        mov    bx,OFFSET $$MPGSNBASE    ; ^ to linker provided overlay segment fixups
  924. X        mov    si,OFFSET $$MPGSNOVL    ; ^ to linker provided module table
  925. X        mov    di,OFFSET moduletbl    ; ^ to our module table
  926. Xmodloop:
  927. X        mov    al,es:[si]        ; real physical ovl number
  928. X        xor    ah,ah
  929. X        add    ax,ovltblbse        ; ovlctlseg address
  930. X        mov    [di],ax         ; save in module table
  931. X        mov    ax,es:[bx]        ; get seg fixup
  932. X        sub    ax,ovlrootcode        ; adjust for relative reference
  933. X        mov    [di+2],ax        ; save in module table
  934. X        add    di,4
  935. X        add    bx,2
  936. X        inc    si
  937. X        loop    modloop
  938. X        pop    es
  939. X        pop    ds
  940. X        pop    bp
  941. X        pop    di
  942. X        pop    si
  943. X        pop    dx
  944. X        pop    cx
  945. X        pop    bx
  946. X        pop    ax            ; restore the world
  947. X        jmp    $$MAIN            ; And away we go!
  948. X
  949. X$$OVLINIT    ENDP
  950. X
  951. X;-------------------------------------------------------------------------------
  952. X
  953. Xovlmgr        PROC    FAR            ; This is the it!
  954. X
  955. X        ASSUME    DS:NOTHING,ES:NOTHING
  956. X
  957. XIFDEF i386
  958. X        OP32
  959. XENDIF
  960. X        mov    sireg,si        ; preserve si
  961. X        mov    dsreg,ds        ; and ds
  962. X        pop    si            ; retrieve caller ip
  963. X        pop    ds            ;     "      "    cs
  964. X        push    ax
  965. X        push    bx
  966. X        cld
  967. X        lodsb                ; module # to call
  968. X        xor    ah,ah
  969. X        mov    bx,ax
  970. X        lodsw                ; offset in ovl to call
  971. X        mov    WORD PTR farcall,ax    ; into trampoline
  972. X        mov    ax,si
  973. X        mov    si,curovl        ; get stack frame pointer
  974. X        add    si,6            ; update stack
  975. X        mov    cs:[si-4],ds        ; save return seg
  976. X        mov    cs:[si-2],ax        ; and return offset
  977. X
  978. X        shl    bx,1
  979. X        shl    bx,1            ; * 4 (2 words/entry in module tbl)
  980. X        add    bx,OFFSET moduletbl
  981. X        mov    ds,cs:[bx]        ; ovl tbl entry
  982. X        mov    ax,cs:[bx+2]        ; segment fixup
  983. X        mov    cs:[si],ds        ; ovl entry into stack frame
  984. X        mov    curovl,si
  985. X
  986. X        ASSUME    DS:ovltbl
  987. X
  988. XIFDEF i386
  989. X        OP32
  990. XENDIF
  991. X        mov    si,WORD PTR ovltim    ; lru time stamp
  992. XIFDEF i386
  993. X        OP32
  994. XENDIF
  995. X        inc    si            ; time passes!
  996. XIFDEF i386
  997. X        OP32
  998. XENDIF
  999. X        mov    WORD PTR ovltim,si    ; update global clock
  1000. XIFDEF i386
  1001. X        OP32
  1002. XENDIF
  1003. X        mov    WORD PTR ovllrudat,si    ; as well as ovl clock
  1004. XIFNDEF i386
  1005. X        mov    si,WORD PTR ovltim+2
  1006. X        jz    ininc            ; dword increment
  1007. Xcryupcdon:
  1008. X        mov    WORD PTR ovllrudat+2,si ; as well as ovl clock
  1009. XENDIF
  1010. X        test    ovlflg,MASK loaded    ; ovl loaded?
  1011. X        jz    inload            ; load it or map it then.
  1012. Xovlloadedupc:
  1013. X        inc    ovlinvcnt
  1014. X        add    ax,ovlmemblk        ; add fixup and segment address
  1015. X        mov    WORD PTR farcall+2,ax    ; into trampoline
  1016. XIFDEF i386
  1017. X        OP32
  1018. XENDIF
  1019. X        mov    si,sireg        ; retore all registers
  1020. X        mov    ds,dsreg
  1021. X        pop    bx
  1022. X        pop    ax
  1023. X        popf                ; don't forget these!
  1024. X        call    DWORD PTR farcall    ; and GO
  1025. X        pushf                ; preserve registers again!
  1026. X        mov    dsreg,ds
  1027. XIFDEF i386
  1028. X        OP32
  1029. XENDIF
  1030. X        mov    sireg,si
  1031. X        mov    si,curovl        ; stack frame pointer
  1032. X        mov    ds,cs:[si]
  1033. X        dec    ovlinvcnt
  1034. X        sub    si,6            ; adjust stack
  1035. X        mov    ds,cs:[si]        ; retrieve ovl tbl entry
  1036. X        push    cs:[si+2]        ; set return address
  1037. X        push    cs:[si+4]
  1038. X        mov    curovl,si
  1039. XIFDEF i386
  1040. X        OP32
  1041. XENDIF
  1042. X        mov    si,WORD PTR ovltim    ; do the lru thing again
  1043. XIFDEF i386
  1044. X        OP32
  1045. XENDIF
  1046. X        inc    si
  1047. XIFDEF i386
  1048. X        OP32
  1049. XENDIF
  1050. X        mov    WORD PTR ovltim,si
  1051. XIFDEF i386
  1052. X        OP32
  1053. XENDIF
  1054. X        mov    WORD PTR ovllrudat,si
  1055. XIFNDEF i386
  1056. X        mov    si,WORD PTR ovltim+2
  1057. X        jz    outinc
  1058. Xcrydncdon:
  1059. X        mov    WORD PTR ovllrudat+2,si
  1060. XENDIF
  1061. X        test    ovlflg,MASK loaded    ; ovl loaded?
  1062. X        jz    outload         ; better get it before someone notices
  1063. Xjmpback:
  1064. XIFDEF i386
  1065. X        OP32
  1066. XENDIF
  1067. X        mov    si,sireg        ; get registers back
  1068. X        mov    ds,dsreg
  1069. X        iret                ; and GO back
  1070. X
  1071. XIFNDEF i386
  1072. Xininc:
  1073. X        inc    si
  1074. X        mov    WORD PTR ovltim+2,si    ; update global and
  1075. X        jmp    cryupcdon
  1076. XENDIF
  1077. X
  1078. Xinload:
  1079. X        test    ovlflg,MASK ems
  1080. X        jz    infile
  1081. X        push    ax
  1082. X        mov    ax,ovlemshdl
  1083. X        call    mappage
  1084. X        pop    ax
  1085. X        jmp    ovlloadedupc
  1086. Xinfile:
  1087. X        call    loadoverlay        ; self explanatory
  1088. X        jmp    ovlloadedupc
  1089. X
  1090. XIFNDEF i386
  1091. Xoutinc:
  1092. X        inc    si
  1093. X        mov    WORD PTR ovltim+2,si
  1094. X        jmp    crydncdon
  1095. XENDIF
  1096. X
  1097. Xoutload:
  1098. X        test    ovlflg,MASK ems
  1099. X        jz    outfile
  1100. X        push    ax
  1101. X        mov    ax,ovlemshdl
  1102. X        call    mappage
  1103. X        pop    ax
  1104. X        jmp    jmpback
  1105. Xoutfile:
  1106. X        call    loadoverlay
  1107. X        jmp    jmpback
  1108. X
  1109. Xovlmgr        ENDP
  1110. X
  1111. X;-------------------------------------------------------------------------------
  1112. X
  1113. Xloadoverlay    PROC    NEAR            ; load overlay pointed to by es
  1114. X
  1115. X        ASSUME    DS:NOTHING,ES:ovltbl
  1116. X
  1117. XIFDEF i386
  1118. X        OP32
  1119. X        pusha                   ; eax,ecx,edx,ebx,esp,ebp,esi,edi
  1120. XELSE
  1121. X        push    ax
  1122. X        push    cx
  1123. X        push    dx
  1124. X        push    bx
  1125. X        push    bp
  1126. X        push    si
  1127. X        push    di
  1128. XENDIF
  1129. X        push    ds
  1130. X        push    es            ; just in case
  1131. X        mov    ax,ds
  1132. X        mov    es,ax
  1133. X        cmp    ovlinvcnt,0
  1134. X        jnz    fxdadr            ; Yup, it's a toughie
  1135. X        mov    ax,ovlsiz        ; How much?
  1136. X        call    getpages        ; never fail mem alloc, you bet.
  1137. X        jmp    gleaner
  1138. Xfxdadr:
  1139. X        call    releasepages        ; free memory where this ovl should be loaded
  1140. Xgleaner:
  1141. X        add    ax,MEMCTLBLKSIZ     ; skip mem ctl blk
  1142. X        mov    ovlmemblk,ax        ; memory block to use
  1143. X        mov    ds,ax
  1144. X        mov    dx,ovlfiloff        ; where in the file is it?
  1145. X        mov    cl,dh
  1146. X        mov    dh,dl
  1147. X        xor    ch,ch
  1148. X        xor    dl,dl
  1149. X        shl    dx,1
  1150. X        rcl    cx,1            ; cx:dx = dx * 512
  1151. X        mov    ax,ovlhdrsiz
  1152. X        push    cx
  1153. X        push    dx
  1154. X        add    dx,ax
  1155. X        adc    cx,0            ; position to code
  1156. X        mov    ah,DOSSEEK        ; lseek to code
  1157. X        mov    al,0            ; from beginning of file
  1158. X        mov    bl,ovlflg
  1159. X        and    bx,MASK file
  1160. X        mov    bx,ovlfilhdl[bx]     ; never closing handle
  1161. X        int    DOS
  1162. X        jc    burnhead        ; oops!
  1163. X        xor    dx,dx            ; buf = ds:0
  1164. X        mov    cx,ovlsiz        ; number of paragraphs to load
  1165. X        shl    cx,1
  1166. X        shl    cx,1
  1167. X        shl    cx,1
  1168. X        shl    cx,1            ; * 16 = number of bytes
  1169. X        mov    ah,DOSREAD        ; prevent random DOS behaviour
  1170. X        int    DOS            ; read in code
  1171. X        jc    burnhead        ; double oops!
  1172. X        pop    dx
  1173. X        pop    cx            ; position of hdr
  1174. X        mov    ah,DOSSEEK        ; lseek to hdr
  1175. X        mov    al,0            ; from beginning of file
  1176. X        mov    bl,ovlflg
  1177. X        and    bx,MASK file
  1178. X        mov    bx,ovlfilhdl[bx]     ; never closing handle
  1179. X        int    DOS
  1180. X        jc    burnhead        ; oops!
  1181. X        mov    cx,EXEHDRTMPSIZ     ; reloc buffer size
  1182. X        mov    dx,OFFSET hdr
  1183. X        push    ds
  1184. X        mov    ax,cs
  1185. X        mov    ds,ax
  1186. X        mov    ah,DOSREAD        ; prevent random DOS behaviour
  1187. X        int    DOS            ; read in header
  1188. X        pop    ds
  1189. X        jc    burnhead        ; double oops!
  1190. X
  1191. X        call    ovlrlc            ; perform relocation normally done by DOS EXE loader
  1192. X        pop    es            ; retrieve ovl tbl entry
  1193. X        pop    ds
  1194. X
  1195. X        ASSUME    DS:ovltbl,ES:NOTHING
  1196. X
  1197. X        or    ovlflg,MASK loaded    ; because it is now
  1198. XIFDEF i386
  1199. X        OP32
  1200. X        popa
  1201. XELSE
  1202. X        pop    di
  1203. X        pop    si
  1204. X        pop    bp
  1205. X        pop    bx
  1206. X        pop    dx
  1207. X        pop    cx
  1208. X        pop    ax
  1209. XENDIF
  1210. X        ret
  1211. X
  1212. Xburnhead:
  1213. X        mov    al,FILEIOERR        ; some kind of I/O error
  1214. X        jmp    putserr
  1215. X
  1216. Xloadoverlay    ENDP
  1217. X
  1218. X;-------------------------------------------------------------------------------
  1219. X
  1220. Xovlrlc        PROC    NEAR            ; ds:0 -> the overlay to relocate
  1221. X
  1222. X        ASSUME    DS:NOTHING,ES:ovltbl
  1223. X
  1224. X        mov    si,OFFSET hdr
  1225. X        mov    bp,si
  1226. X        add    bp,EXEHDRTMPSIZ     ; ^ to end of buf+1
  1227. X        mov    cx,cs:[si.relocitems]    ; roto-count
  1228. X        jcxz    relocdone        ; not such a good idea, after all
  1229. X        mov    di,ds
  1230. X        sub    di,ovlrootcode        ; segment fixup value
  1231. X        add    si,cs:[si.reloctbloff]    ; ^ relocation table
  1232. Xdorelocs:                    ; labels don't GET comments
  1233. X        cmp    si,bp            ; past the end ?
  1234. X        jc    getoffsetl
  1235. X        call    getnxtreloc        ; get another hunk
  1236. Xgetoffsetl:
  1237. X        mov    bl,cs:[si]        ; offset into load module
  1238. X        inc    si
  1239. X        cmp    si,bp            ; past the end ?
  1240. X        jc    getoffseth
  1241. X        call    getnxtreloc        ; get another hunk
  1242. Xgetoffseth:
  1243. X        mov    bh,cs:[si]        ; offset into load module
  1244. X        inc    si
  1245. X        cmp    si,bp            ; past the end ?
  1246. X        jc    getsegmentl
  1247. X        call    getnxtreloc        ; get another hunk
  1248. Xgetsegmentl:
  1249. X        mov    al,cs:[si]        ; segment in load module (zero reference)
  1250. X        inc    si
  1251. X        cmp    si,bp            ; past the end ?
  1252. X        jc    getsegmenth
  1253. X        call    getnxtreloc        ; get another hunk
  1254. Xgetsegmenth:
  1255. X        mov    ah,cs:[si]        ; segment in load module (zero reference)
  1256. X        inc    si
  1257. X        add    ax,pspadd        ; now it is psp relative
  1258. X        add    ax,di            ; and now it is relative to the actual load address
  1259. X        mov    ds,ax
  1260. X        mov    ax,[bx]            ; pickup item to relocate
  1261. X        add    ax,pspadd        ; make it psp relative
  1262. X        cmp    ax,ovlrootcode        ; is it below the OVERLAY_AREA?
  1263. X        jc    reloccomputed        ; yup. it's relocated
  1264. X        cmp    ax,ovldata        ; is it above OVERLAY_AREA
  1265. X        jnc    reloccomputed        ; yup. it's relocated
  1266. X        add    ax,di            ; it's in OVERLAY_AREA, this one's ours.
  1267. Xreloccomputed:
  1268. X        mov    [bx],ax            ; RAM it home!?!
  1269. X        loop    dorelocs        ; what goes around, comes around.
  1270. Xrelocdone:    ret
  1271. X
  1272. Xovlrlc        ENDP
  1273. X
  1274. X;-------------------------------------------------------------------------------
  1275. X
  1276. Xgetnxtreloc    PROC    NEAR
  1277. X
  1278. X        ASSUME    DS:NOTHING,ES:ovltbl
  1279. X
  1280. X        push    bx
  1281. X        push    cx
  1282. X        push    di
  1283. X        push    bp
  1284. X        push    ds
  1285. X        push    es
  1286. X        mov    cx,EXEHDRTMPSIZ     ; reloc buffer size
  1287. X        mov    dx,OFFSET hdr
  1288. X        mov    ax,cs
  1289. X        mov    ds,ax
  1290. X        mov    bl,ovlflg
  1291. X        and    bx,MASK file
  1292. X        mov    bx,ovlfilhdl[bx]     ; never closing handle
  1293. X        mov    ah,DOSREAD        ; prevent random DOS behaviour
  1294. X        int    DOS            ; read in header
  1295. X        jnc    nxtrelocok
  1296. X        jmp    burnhead        ; double oops!
  1297. Xnxtrelocok:
  1298. X        mov    si,OFFSET hdr
  1299. X        pop    es
  1300. X        pop    ds
  1301. X        pop    bp
  1302. X        pop    di
  1303. X        pop    cx
  1304. X        pop    bx
  1305. X        ret
  1306. X
  1307. Xgetnxtreloc    ENDP
  1308. X
  1309. X;-------------------------------------------------------------------------------
  1310. X
  1311. Xgetvictim    PROC    NEAR            ; select a victim to discard (and free up some memory)
  1312. X
  1313. X        ASSUME    DS:ovltbl,ES:NOTHING
  1314. X
  1315. X        push    bx
  1316. X        push    cx
  1317. X        push    dx
  1318. X        push    si
  1319. X        push    di
  1320. X        push    bp
  1321. X        push    ds
  1322. X        mov    ds,ovltblbse        ; ^ ovl tbl
  1323. XIFDEF i386
  1324. X        OP32
  1325. XENDIF
  1326. X        xor    ax,ax            ; will contain the low word of lru
  1327. XIFDEF i386
  1328. X        OP32
  1329. XENDIF
  1330. X        mov    dx,ax            ; will contain the high word of lru
  1331. X        mov    bp,ax            ; will contain ovl tbl entry
  1332. X        mov    bx,ax            ; ovl tbl ptr
  1333. X        mov    cx,ovlcnt
  1334. Xfoon1:
  1335. X        test    ovlflg[bx],MASK locked
  1336. X        jnz    skip1
  1337. X        test    ovlflg[bx],MASK ems
  1338. X        jnz    foon2
  1339. X        test    ovlflg[bx],MASK loaded
  1340. X        jz    skip1
  1341. Xfoon2:
  1342. XIFDEF i386
  1343. X        OP32
  1344. XENDIF
  1345. X        mov    si,WORD PTR ovltim
  1346. XIFNDEF i386
  1347. X        mov    di,WORD PTR ovltim+2
  1348. XENDIF
  1349. XIFDEF i386
  1350. X        OP32
  1351. XENDIF
  1352. X        sub    si,WORD PTR ovllrudat[bx]
  1353. XIFNDEF i386
  1354. X        sbb    di,WORD PTR ovllrudat[bx+2]
  1355. XENDIF
  1356. XIFDEF i386
  1357. X        OP32
  1358. X        cmp    dx,si
  1359. XELSE
  1360. X        cmp    dx,di
  1361. XENDIF
  1362. XIFDEF i386
  1363. X        jnc    skip1
  1364. XELSE
  1365. X        jc    better1
  1366. X        jnz    skip1
  1367. X        cmp    ax,si
  1368. X        jnc    skip1
  1369. XENDIF
  1370. Xbetter1:
  1371. XIFDEF i386
  1372. X        OP32
  1373. X        mov    dx,si
  1374. XELSE
  1375. X        mov    ax,si
  1376. X        mov    dx,di
  1377. XENDIF
  1378. X        mov    bp,bx
  1379. Xskip1:
  1380. X        add    bx,OVLSEGSIZ
  1381. X        loop    foon1
  1382. X        or    bp,bp            ; were we more successful this time?
  1383. X        jnz    gotvictim        ; now we got one.
  1384. Xnomoremem:
  1385. X        mov    al,VICTIMERR        ; were really %$# now!
  1386. X        jmp    putserr
  1387. Xgotvictim:
  1388. X        shr    bp,1            ; convert offset to segment
  1389. X        shr    bp,1
  1390. X        shr    bp,1
  1391. X        shr    bp,1
  1392. X        mov    ax,ds
  1393. X        add    ax,bp
  1394. X        pop    ds
  1395. X        pop    bp
  1396. X        pop    di
  1397. X        pop    si
  1398. X        pop    dx
  1399. X        pop    cx
  1400. X        pop    bx
  1401. X        ret
  1402. X
  1403. Xgetvictim    ENDP
  1404. X
  1405. X;-------------------------------------------------------------------------------
  1406. X
  1407. Xint21        PROC    FAR
  1408. X
  1409. X; free almost all overlay memory if app. tries to call the DOS exec function.
  1410. X
  1411. X        cmp    ah,DOSEXEC
  1412. X        jz    freeall
  1413. X        cmp    ah,TERMINATE
  1414. X        jz    saybyebye
  1415. Xnotours:
  1416. X        jmp    cs:oldint21
  1417. Xsaybyebye:
  1418. X        mov    al,NOERR        ; return code 0
  1419. X        jmp    putserr
  1420. Xfreeall:
  1421. X        or    al,al            ; is it load and exec?
  1422. X        jnz    notours
  1423. X        push    ax
  1424. X        push    cx
  1425. X        push    dx
  1426. X        push    bx
  1427. X        push    bp
  1428. X        push    si
  1429. X        push    di
  1430. X        push    es
  1431. X        push    ds            ; preserve calling env.
  1432. X
  1433. X        ASSUME    DS:NOTHING,ES:ovltbl
  1434. X
  1435. X        mov    es,ovltblbse
  1436. X        mov    cx,ovlcnt        ; unload all overlays that are
  1437. X        mov    bx,OVLSEGSIZ        ; in EMS or are in alloced mem.
  1438. X        dec    cx
  1439. Xmemunloadlp:
  1440. X        test    [bx.ovlflg],MASK ems
  1441. X        jnz    memunload
  1442. X        test    [bx.ovlflg],MASK loaded
  1443. X        jz    nxtmemunload
  1444. X        mov    ax,[bx.ovlmemblk]
  1445. X        sub    ax,MEMCTLBLKSIZ
  1446. X        cmp    ax,memblks        ; allocated memory ?
  1447. X        jc    nxtmemunload
  1448. Xmemunload:
  1449. X        and    [bx.ovlflg],NOT MASK loaded ; you're outta there!
  1450. Xnxtmemunload:
  1451. X        add    bx,OVLSEGSIZ
  1452. X        loop    memunloadlp
  1453. X
  1454. X        mov    curemshandle,-1     ; no current handle anymore
  1455. X
  1456. X        mov    ax,memblks
  1457. X        cmp    ax,-1
  1458. X        jz    nosecondblk
  1459. X        mov    es,ax            ; ^ to second mem blk
  1460. X        mov    es,es:memblkprv     ; get previous pointer
  1461. X        mov    es:memblknxt,0        ; no other blocks after this one
  1462. Xnosecondblk:
  1463. X        mov    cx,16            ; do all allocated mem blocks
  1464. X        mov    si,OFFSET memblks
  1465. Xfreememblklp:
  1466. X        mov    ax,cs:[si]        ; get memory blk segment
  1467. X        cmp    ax,-1            ; was one ever allocated?
  1468. X        jz    nxtmemblklp        ; nope
  1469. X        mov    es,ax
  1470. X        mov    ah,DOSFREE        ; must free it.
  1471. X        int    DOS
  1472. X        mov    WORD PTR cs:[si],-1
  1473. Xnxtmemblklp:
  1474. X        add    si,2
  1475. X        loop    freememblklp
  1476. X
  1477. X        call    rstvectors        ; restore all int vectors
  1478. X
  1479. X        mov    bp,sp
  1480. X        push    [bp+22]         ; ensure returned flags are based on user's!
  1481. X        popf
  1482. X        pop    ds
  1483. X        pop    es
  1484. X        pop    di
  1485. X        pop    si
  1486. X        pop    bp
  1487. X        pop    bx
  1488. X        pop    dx
  1489. X        pop    cx
  1490. X        pop    ax
  1491. X
  1492. X        mov    ssreg,ss        ; preserve these due to a
  1493. X        mov    spreg,sp        ; DOS bug.
  1494. X
  1495. X        int    DOS            ; allow DOS to continue!
  1496. X
  1497. X        mov    ss,ssreg
  1498. X        mov    sp,spreg
  1499. X
  1500. X        push    ax
  1501. X        push    cx
  1502. X        push    dx
  1503. X        push    bx
  1504. X        push    bp
  1505. X        push    si
  1506. X        push    di
  1507. X        push    es
  1508. X        push    ds            ; preserve calling env.
  1509. X        mov    bp,sp
  1510. X        pushf
  1511. X        pop    [bp+22]         ; fix return flags
  1512. X
  1513. X        call    getmoreram        ; re-allocate our memory
  1514. X        call    setvectors        ; patch vectors again
  1515. X
  1516. X        pop    ds
  1517. X        pop    es
  1518. X        pop    di
  1519. X        pop    si
  1520. X        pop    bp
  1521. X        pop    bx
  1522. X        pop    dx
  1523. X        pop    cx
  1524. X        pop    ax
  1525. X        iret
  1526. X
  1527. Xint21        ENDP
  1528. X
  1529. X;-------------------------------------------------------------------------------
  1530. X
  1531. Xreleasepages    PROC    NEAR            ; Arg in es, result in ax
  1532. X
  1533. X; release any memory (and overlays) where this overlay should reside
  1534. X
  1535. X        ASSUME    DS:NOTHING,ES:ovltbl
  1536. X
  1537. X        mov    bx,ovlmemblk        ; start of memory to release
  1538. X        sub    bx,MEMCTLBLKSIZ
  1539. X        mov    dx,bx
  1540. X        add    dx,es:ovlsiz
  1541. X        add    dx,MEMCTLBLKSIZ     ; end of memory to release
  1542. X        mov    ax,ovlemshdl
  1543. X        cmp    ax,-1
  1544. X        jz    doitagain
  1545. X        call    mappage
  1546. X        or    ovlflg,MASK ems
  1547. X        mov    ax,emsframe
  1548. X        jmp    dvart
  1549. Xdoitagain:
  1550. X        mov    ax,memblk1st        ; first memory blk
  1551. X        jmp    dvart
  1552. Xdvartloop:
  1553. X        mov    ds,ax            ; memory blk to check
  1554. X        cmp    bx,ax            ; does it start below the memory to release?
  1555. X        jnc    dvartsmaller        ; yup
  1556. X        cmp    ax,dx            ; does it start above?
  1557. X        jnc    dvartnocore        ; yup
  1558. X        call    killmem         ; it's in the way. Zap it.
  1559. X        jmp    dvartloop
  1560. Xdvartsmaller:
  1561. X        add    ax,ds:memblksiz     ; end of this memory blk
  1562. X        cmp    bx,ax            ; does it end below the memory to release?
  1563. X        jnc    dvartsilly        ; yup
  1564. X        test    ds:memblkflg,MASK_used
  1565. X        jz    dvartfree
  1566. X        call    killmem         ; Oh well, zap it too.
  1567. X        add    ax,ds:memblksiz     ; end of this memory blk
  1568. Xdvartfree:
  1569. X        cmp    ax,dx            ; does it end in the memory to be released?
  1570. X        jc    dvartsilly
  1571. Xdvartgotblk:
  1572. X        mov    ax,ds            ; this is it!
  1573. X        mov    cx,bx
  1574. X        sub    cx,ax            ; # of paragraphs between start of memory to release and mem blk
  1575. X        jz    unsplit
  1576. X        push    es
  1577. X        call    splitblk
  1578. X        or    es:memblkflg,MASK_used    ; set high block used
  1579. X        call    mergemem        ; merge remaining free memory
  1580. X        mov    ax,es
  1581. X        mov    ds,ax
  1582. X        pop    es
  1583. Xunsplit:
  1584. X        mov    cx,es:ovlsiz
  1585. X        add    cx,MEMCTLBLKSIZ     ; paragraphs needed to load ovl
  1586. X        jmp    splitblklow        ; split remaining block
  1587. Xdvartsilly:
  1588. X        mov    ax,ds:memblknxt
  1589. Xdvart:
  1590. X        or    ax,ax            ; end of mem list?
  1591. X        jz    dvartnocore
  1592. X        jmp    dvartloop        ; play it again Sam.
  1593. Xdvartnocore:
  1594. X        mov    al,RELERR        ; super OOPS!
  1595. X        jmp    putserr
  1596. X
  1597. Xreleasepages    ENDP
  1598. X
  1599. X;-------------------------------------------------------------------------------
  1600. X
  1601. Xgetpages    PROC    NEAR            ; get enough memory to load ovl
  1602. X
  1603. X        ASSUME    DS:NOTHING,ES:ovltbl
  1604. X
  1605. X        mov    ovlemshdl,-1        ; clear any EMS stuff
  1606. X        and    ovlflg,NOT MASK ems
  1607. X        mov    cx,ax
  1608. X        add    cx,MEMCTLBLKSIZ     ; total paragraphs needed
  1609. Xdorkagain:
  1610. X        call    largestmem        ; find largest free blk
  1611. X        cmp    dx,cx            ; large enough?
  1612. X        jnc    gotdork         ; yup.
  1613. X        call    getemsmem        ; try to allocate ems
  1614. X        cmp    dx,cx            ; any available ?
  1615. X        jnc    gotdork
  1616. Xdorkkill:
  1617. X        call    getvictim        ; select a victim to release
  1618. X        call    killovl         ; kill the selected victim
  1619. X        jmp    dorkagain
  1620. Xgotdork:
  1621. X        jmp    splitblklow        ; split the free blk
  1622. X
  1623. Xgetpages    ENDP
  1624. X
  1625. X;-------------------------------------------------------------------------------
  1626. X
  1627. Xsplitblklow    PROC    NEAR
  1628. X
  1629. X; split a block of memory returning the lower one to be used.
  1630. X
  1631. X        ASSUME    DS:NOTHING,ES:NOTHING
  1632. X
  1633. X        push    es
  1634. X        or    ds:memblkflg,MASK_used    ; set low block used
  1635. X        call    splitblk
  1636. X        jc    splitlowdone
  1637. X        push    ds
  1638. X        mov    ax,es
  1639. X        mov    ds,ax
  1640. X        call    mergemem        ; merge remaining free memory
  1641. X        pop    ds
  1642. Xsplitlowdone:
  1643. X        pop    es
  1644. X        mov    ds:memblkovl,es     ; fix ptr to ovl
  1645. X        mov    ax,ds            ; return lower blk segment
  1646. X        ret
  1647. X
  1648. Xsplitblklow    ENDP
  1649. X
  1650. X;-------------------------------------------------------------------------------
  1651. X
  1652. Xsplitblk    PROC    NEAR
  1653. X
  1654. X        ASSUME    DS:NOTHING,ES:NOTHING
  1655. X
  1656. X        mov    ax,ds
  1657. X        add    ax,cx
  1658. X        mov    es,ax            ; ^ to upper blk to be created
  1659. X        mov    ax,ds:memblksiz
  1660. X        sub    ax,cx
  1661. X        jbe    nofix            ; must be at least 1 para remaining to split
  1662. X        mov    ds:memblksiz,cx     ; fix blk sizes
  1663. X        mov    es:memblksiz,ax
  1664. X        mov    ax,ds:memblknxt     ; fix pointers
  1665. X        mov    es:memblknxt,ax
  1666. X        mov    ds:memblknxt,es
  1667. X        mov    es:memblkprv,ds
  1668. X        mov    es:memblkflg,0        ; set upper to not used
  1669. X        mov    ax,es:memblknxt
  1670. X        or    ax,ax
  1671. X        jz    nofix
  1672. X        push    ds
  1673. X        mov    ds,ax            ; fix blk after upper to point to upper
  1674. X        mov    ds:memblkprv,es
  1675. X        pop    ds
  1676. X        clc
  1677. X        ret
  1678. Xnofix:
  1679. X        stc
  1680. X        ret
  1681. X
  1682. Xsplitblk    ENDP
  1683. X
  1684. X;-------------------------------------------------------------------------------
  1685. X
  1686. Xlargestmem    PROC    NEAR    ; returns seg in ax, size in dx
  1687. X                ; retruns first block that's large enough if possible
  1688. X
  1689. X        ASSUME    DS:NOTHING,ES:ovltbl
  1690. X
  1691. X        mov    ax,memblk1st        ; first mem blk
  1692. X        xor    dx,dx            ; largest size found
  1693. X        jmp    gook
  1694. Xgookloop:
  1695. X        mov    ds,ax
  1696. X        test    ds:memblkflg,MASK_used    ; is this blk used?
  1697. X        jnz    gookme            ; yup
  1698. X        cmp    ds:memblksiz,cx     ; is it large enough?
  1699. X        jc    gookme            ; nope
  1700. X        mov    dx,ds:memblksiz     ; got one!
  1701. X        ret
  1702. Xgookme:
  1703. X        mov    ax,ds:memblknxt
  1704. Xgook:
  1705. X        or    ax,ax            ; end of list?
  1706. X        jnz    gookloop        ; around and around
  1707. X        ret
  1708. X
  1709. Xlargestmem    ENDP
  1710. X
  1711. X;-------------------------------------------------------------------------------
  1712. X
  1713. Xkillmem     PROC    NEAR
  1714. X
  1715. X        ASSUME    DS:NOTHING,ES:ovltbl
  1716. X
  1717. X        test    ds:memblkflg,MASK_used    ; is it used?
  1718. X        jz    memnotused        ; don't kill ovl
  1719. X        push    es
  1720. X        mov    es,ds:memblkovl
  1721. X        and    ovlflg,NOT MASK loaded    ; zap ovl associated with this blk
  1722. X        and    ovlflg,NOT MASK ems
  1723. X        pop    es
  1724. Xmemnotused:
  1725. X        jmp    mergemem        ; merge free memory
  1726. X
  1727. Xkillmem     ENDP
  1728. X
  1729. X;-------------------------------------------------------------------------------
  1730. X
  1731. Xkillovl     PROC    NEAR        ; preserves bx
  1732. X
  1733. X        ASSUME    DS:ovltbl,ES:NOTHING
  1734. X
  1735. X        mov    ds,ax
  1736. X        and    ovlflg,NOT MASK loaded    ; ovl no longer loaded
  1737. X        test    ovlflg,MASK ems     ; was it in ems ?
  1738. X        jz    noemskill
  1739. X        and    ovlflg,NOT MASK ems    ; no longer in ems
  1740. X        mov    ax,ovlemshdl
  1741. X        call    mappage
  1742. Xnoemskill:
  1743. X        mov    ax,ovlmemblk        ; get mem blk
  1744. X        sub    ax,MEMCTLBLKSIZ
  1745. X        mov    ds,ax
  1746. X        jmp    mergemem        ; merge free memory
  1747. X
  1748. Xkillovl     ENDP
  1749. X
  1750. X;-------------------------------------------------------------------------------
  1751. X
  1752. Xmergemem    PROC    NEAR
  1753. X
  1754. X; merge physically adjacent free memory blocks. Preserves es. ds -> a free block.
  1755. X
  1756. X        ASSUME    DS:NOTHING,ES:NOTHING
  1757. X
  1758. X        push    dx
  1759. X        push    es
  1760. X        and    ds:memblkflg,NOT MASK_used ; set current free
  1761. X        mov    ax,ds:memblkprv     ; get previous blk
  1762. X        or    ax,ax            ; was there a previous blk?
  1763. X        jz    gibber            ; nope
  1764. X        mov    es,ax
  1765. X        test    es:memblkflg,MASK_used    ; is the previous blk used?
  1766. X        jnz    gibber            ; yup
  1767. X        add    ax,es:memblksiz     ; end of previous blk
  1768. X        mov    dx,ds
  1769. X        cmp    dx,ax            ; physically adjacent?
  1770. X        jnz    gibber            ; nope
  1771. X        mov    ax,ds:memblksiz
  1772. X        add    es:memblksiz,ax     ; adjust size of new larger blk
  1773. X        mov    ax,ds:memblknxt     ; fix pointers
  1774. X        mov    es:memblknxt,ax
  1775. X        or    ax,ax
  1776. X        jz    almostgibber
  1777. X        mov    ds,ax            ; fix pointer of next blk
  1778. X        mov    ds:memblkprv,es
  1779. Xalmostgibber:
  1780. X        mov    ax,es
  1781. X        mov    ds,ax            ; new blk segment
  1782. Xgibber:
  1783. X        mov    ax,ds:memblknxt     ; get next blk
  1784. X        or    ax,ax            ; was there a next blk?
  1785. X        jz    killdone        ; nope
  1786. X        mov    es,ax
  1787. X        test    es:memblkflg,MASK_used    ; is the nxt blk used?
  1788. X        jnz    killdone        ; yup
  1789. X        mov    ax,ds
  1790. X        add    ax,ds:memblksiz     ; end of this blk
  1791. X        mov    dx,es
  1792. X        cmp    ax,dx            ; physically adjacent?
  1793. X        jnz    killdone        ; nope
  1794. X        mov    ax,es:memblksiz
  1795. X        add    ds:memblksiz,ax     ; adjust size of new larger blk
  1796. X        mov    ax,es:memblknxt     ; fix pointers
  1797. X        mov    ds:memblknxt,ax
  1798. X        or    ax,ax
  1799. X        jz    killdone
  1800. X        mov    es,ax            ; fix pointer of blk after nxt
  1801. X        mov    es:memblkprv,ds
  1802. Xkilldone:
  1803. X        and    ds:memblkflg,NOT MASK_used ; make sure it's free
  1804. X        pop    es
  1805. X        pop    dx
  1806. X        mov    ax,ds
  1807. X        ret
  1808. X
  1809. Xmergemem    ENDP
  1810. X
  1811. X;-------------------------------------------------------------------------------
  1812. X
  1813. Xgetmoreram    PROC    NEAR            ; try to alloc remaining pieces
  1814. X                        ; of memory if any
  1815. X        ASSUME    DS:NOTHING,ES:NOTHING    ; return dx = biggest block
  1816. X
  1817. X        push    cx
  1818. X        push    bx
  1819. X        push    si
  1820. X        push    di
  1821. X        push    ds
  1822. X        push    es
  1823. X        xor    dx,dx
  1824. X        mov    ax,memblk1st
  1825. Xnxtlowblk:
  1826. X        mov    ds,ax
  1827. X        mov    ax,ds:memblknxt
  1828. X        or    ax,ax
  1829. X        jnz    nxtlowblk
  1830. X
  1831. X        mov    si,OFFSET memblks    ; a place to store the handles
  1832. X        mov    di,OFFSET tempmem    ; a place to store the rejects
  1833. X        mov    cx,16            ; 16 more max
  1834. Xgetramlp:
  1835. X        mov    ah,DOSALLOC
  1836. X        mov    bx,0ffffh        ; Everything
  1837. X        int    DOS
  1838. X        cmp    bx,10h            ; nothing smaller than .25k please
  1839. X        jc    gotallram
  1840. X        mov    ah,DOSALLOC        ; allocate our own memory
  1841. X        int    DOS
  1842. X        jc    gotallram        ; oops!
  1843. X        cmp    ax,ovltblbse        ; is it after our first mem blk?
  1844. X        jc    releaseblk
  1845. X        cmp    dx,bx
  1846. X        jnc    notbigger
  1847. X        mov    dx,bx
  1848. Xnotbigger:
  1849. X        mov    cs:[si],ax        ; save it
  1850. X        mov    es,ax
  1851. X        mov    es:memblkflg,0        ; clear mem flags
  1852. X        mov    es:memblknxt,0        ; set next to nothing
  1853. X        mov    es:memblkovl,0        ; no overlays loaded
  1854. X        mov    es:memblkprv,ds     ; point to previous
  1855. X        mov    es:memblksiz,bx     ; allocated memory block size
  1856. X        mov    ds:memblknxt,es     ; point to next
  1857. X        add    si,2
  1858. X        mov    ds,ax
  1859. X        jmp    short getnxtram
  1860. Xreleaseblk:
  1861. X        mov    cs:[di],ax
  1862. X        add    di,2
  1863. Xgetnxtram:
  1864. X        loop    getramlp
  1865. Xgotallram:
  1866. X        mov    si,OFFSET tempmem
  1867. X        mov    cx,16
  1868. Xreleaselp:
  1869. X        mov    ax,cs:[si]
  1870. X        cmp    ax,-1
  1871. X        jz    relnext
  1872. X        mov    es,ax
  1873. X        mov    ah,DOSFREE
  1874. X        int    DOS
  1875. X        mov    WORD PTR cs:[si],-1
  1876. Xrelnext:
  1877. X        add    si,2
  1878. X        loop    releaselp
  1879. X        pop    es
  1880. X        pop    ds
  1881. X        pop    di
  1882. X        pop    si
  1883. X        pop    bx
  1884. X        pop    cx
  1885. X        ret
  1886. X
  1887. Xgetmoreram    ENDP
  1888. X
  1889. X;-------------------------------------------------------------------------------
  1890. X
  1891. Xgetemsmem    PROC    NEAR
  1892. X
  1893. X        ASSUME    DS:NOTHING,ES:ovltbl
  1894. X
  1895. X        xor    dx,dx            ; no ems memory
  1896. X        cmp    emmflg,-1
  1897. X        jz    testemsslots
  1898. X        ret
  1899. Xtestemsslots:
  1900. X        mov    curemshandle,-1
  1901. X        mov    di,OFFSET emsmemblks
  1902. X        mov    bx,cx
  1903. X        mov    cx,16
  1904. Xemsfreeslot:
  1905. X        mov    ax,cs:[di]
  1906. X        cmp    ax, -1
  1907. X        jz    gotemsslot
  1908. X        call    mappage
  1909. X        cmp    ax,bx
  1910. X        jnc    foundpage
  1911. X        add    di,2
  1912. X        loop    emsfreeslot
  1913. X        mov    cx,bx
  1914. X        xor    dx,dx
  1915. X        ret
  1916. Xgotemsslot:
  1917. X        mov    cx,bx
  1918. X        mov    bx,4
  1919. X        mov    ah,EMMALLOC
  1920. X        push    cx            ; paranoia ! shouldn't be necessary.
  1921. X        push    di
  1922. X        push    es
  1923. X        int    EMM
  1924. X        pop    es
  1925. X        pop    di
  1926. X        pop    cx
  1927. X        or    ah,ah
  1928. X        jz    gotsomeems
  1929. X        xor    dx,dx
  1930. X        ret
  1931. Xgotsomeems:
  1932. X        mov    cs:[di],dx
  1933. X        mov    ovlemshdl,dx
  1934. X        or    ovlflg,MASK ems
  1935. X        mov    ax,dx
  1936. X        call    mapemspages
  1937. X        mov    ax,emsframe
  1938. X        mov    ds,ax
  1939. X        mov    ds:memblkflg,0        ; clear mem flags
  1940. X        mov    ds:memblknxt,0        ; set next to nothing
  1941. X        mov    ds:memblkprv,0        ; set previous to nothing
  1942. X        mov    ds:memblkovl,0        ; no overlay loaded
  1943. X        mov    dx,1000h
  1944. X        mov    ds:memblksiz,dx
  1945. X        ret
  1946. X
  1947. Xfoundpage:
  1948. X        mov    cx,bx
  1949. X        mov    ds,si
  1950. X        mov    dx,ax
  1951. X        mov    ax,cs:[di]
  1952. X        mov    ovlemshdl,ax
  1953. X        or    ovlflg,MASK ems
  1954. X        ret
  1955. X
  1956. Xgetemsmem    ENDP
  1957. X
  1958. X;-------------------------------------------------------------------------------
  1959. X
  1960. Xmappage     PROC    NEAR            ; map a 64K block of EMS mem.
  1961. X
  1962. X        ASSUME    DS:NOTHING,ES:ovltbl
  1963. X
  1964. X        cmp    ax,curemshandle
  1965. X        jnz    doems
  1966. X        ret
  1967. Xdoems:
  1968. X        push    bx
  1969. X        push    dx
  1970. X        push    ds
  1971. X        push    es
  1972. X        call    mapemspages
  1973. X        mov    ax,emsframe
  1974. X        xor    dx,dx
  1975. X        xor    si,si
  1976. Xemsset:
  1977. X        mov    ds,ax
  1978. X        test    ds:memblkflg,MASK_used    ; mem blk used ?
  1979. X        jz    emsfreeblk
  1980. X        mov    es,ds:memblkovl
  1981. X        or    ovlflg,MASK ems OR MASK loaded
  1982. X        jmp    emsnext
  1983. Xemsfreeblk:
  1984. X        mov    ax,ds:memblksiz
  1985. X        cmp    dx,ax
  1986. X        jnc    emsnext
  1987. X        mov    dx,ax
  1988. X        mov    si,ds
  1989. Xemsnext:
  1990. X        mov    ax,ds:memblknxt
  1991. X        or    ax,ax
  1992. X        jnz    emsset
  1993. X
  1994. X        mov    ax,dx
  1995. X        pop    es
  1996. X        pop    ds
  1997. X        pop    dx
  1998. X        pop    bx
  1999. X        ret
  2000. X
  2001. Xmappage     ENDP
  2002. X
  2003. X;-------------------------------------------------------------------------------
  2004. X
  2005. Xmapemspages    PROC    NEAR
  2006. X
  2007. X        ASSUME    DS:NOTHING,ES:ovltbl
  2008. X
  2009. X        push    es
  2010. X        push    bx
  2011. X        push    cx
  2012. X        push    dx
  2013. X        mov    curemshandle,ax
  2014. X        mov    dx,ax
  2015. X        mov    ah,EMMMAP
  2016. X        xor    al,al            ; physical page 0
  2017. X        xor    bx,bx            ; logical page 0
  2018. X        push    dx
  2019. X        int    EMM
  2020. X        pop    dx
  2021. X        or    ah,ah
  2022. X        jnz    emmerror
  2023. X        mov    ah,EMMMAP
  2024. X        mov    al,1            ; physical page 1
  2025. X        mov    bx,1            ; logical page 1
  2026. X        push    dx
  2027. X        int    EMM
  2028. X        pop    dx
  2029. X        or    ah,ah
  2030. X        jnz    emmerror
  2031. X        mov    ah,EMMMAP
  2032. X        mov    al,2            ; physical page 2
  2033. X        mov    bx,2            ; logical page 2
  2034. X        push    dx
  2035. X        int    EMM
  2036. X        pop    dx
  2037. X        or    ah,ah
  2038. X        jnz    emmerror
  2039. X        mov    ah,EMMMAP
  2040. X        mov    al,3            ; physical page 3
  2041. X        mov    bx,3            ; logical page 3
  2042. X        int    EMM
  2043. X        or    ah,ah
  2044. X        jnz    emmerror
  2045. X        mov    es,ovltblbse
  2046. X        mov    cx,ovlcnt
  2047. X        xor    bx,bx
  2048. Xtestems:
  2049. X        test    ovlflg[bx],MASK ems
  2050. X        jz    nxttestems
  2051. X        and    ovlflg[bx],NOT MASK loaded
  2052. Xnxttestems:
  2053. X        add    bx,OVLSEGSIZ
  2054. X        loop    testems
  2055. X        pop    dx
  2056. X        pop    cx
  2057. X        pop    bx
  2058. X        pop    es
  2059. X        ret
  2060. X
  2061. Xemmerror:
  2062. X        mov    al,EMSERR        ; ems manager error
  2063. X        jmp    putserr
  2064. X
  2065. Xmapemspages    ENDP
  2066. X
  2067. X;-------------------------------------------------------------------------------
  2068. X
  2069. Xgethdr        PROC    NEAR            ; read EXE header from handle
  2070. X
  2071. X        ASSUME    DS:NOTHING,ES:NOTHING
  2072. X
  2073. X        mov    dx,OFFSET hdr        ; a place to put it
  2074. X        mov    bx,si
  2075. X        shl    bx,1
  2076. X        mov    bx,ovlfilhdl[bx]     ; the file handle
  2077. Xreadagain:
  2078. X        mov    cx,TYPE EXEHDR        ; header size in bytes
  2079. X        mov    ah,DOSREAD
  2080. X        int    DOS            ; read from file
  2081. X        jc    exegone         ; oops?
  2082. X        cmp    ax,cx            ; got correct number of bytes?
  2083. X        je    gothdr
  2084. XIFNDEF NOSPLIT
  2085. X        cmp    ax,0            ; Anything?
  2086. X        je    gotonxtfil
  2087. XENDIF
  2088. X        jmp    exerotten
  2089. XIFNDEF NOSPLIT
  2090. Xgotonxtfil:
  2091. X        inc    si
  2092. X        cmp    si,MAXFILES+1
  2093. X        je    exegone            ; We're out of files!
  2094. X        mov    bx,si
  2095. X        shl    bx,1
  2096. X        cmp    ovlfilhdl[bx],-1    ; Any more files?
  2097. X        je    gotonxtfil        ; not here.
  2098. X
  2099. X        mov    bx,ovlfilhdl[bx]    ; Slide in new handle
  2100. X        xor    bp,bp            ; reset file offset
  2101. X        jmp    readagain
  2102. XENDIF
  2103. Xgothdr:
  2104. X        cmp    hdr.exesign,EXESIGNUM    ; sanity check
  2105. X        jne    exerotten
  2106. X
  2107. X        ret                ; Wow, it worked!
  2108. Xexegone:
  2109. X        mov    al,NOHDRERR        ; missing overlays!
  2110. X        jmp    putserr            ; You lose!
  2111. XIFNDEF NOSPLIT
  2112. Xexerotten:
  2113. X        mov    al,HDRERR        ; corruption!
  2114. X        jmp    putserr            ; You lose!
  2115. XENDIF
  2116. X
  2117. Xgethdr        ENDP
  2118. X
  2119. X;-------------------------------------------------------------------------------
  2120. X
  2121. Xopenfiles    PROC    NEAR            ; Find our cohorts in crime
  2122. X
  2123. X        push    es
  2124. XIFNDEF NOSPLIT
  2125. X        mov    ah,DOSGETDTA        ; Pick up DTA
  2126. X        int    DOS            ; and
  2127. X        mov    dtaseg,es        ; store
  2128. X        mov    dtaoffset,bx        ; it
  2129. X
  2130. X        push    ds
  2131. X        mov    dx,OFFSET ovldta    ; Set new DTA for file search
  2132. X        mov    ax,cs
  2133. X        mov    ds,ax            ; point to the right seg
  2134. X        mov    ah,DOSSETDTA
  2135. X        int    DOS
  2136. X        pop    ds            ; set this back for upcoming lodsb
  2137. XENDIF
  2138. X        mov    cx,MAXNAMESIZE/2
  2139. X        mov    bx,cs
  2140. X        mov    es,bx
  2141. X        mov    di, OFFSET filestring
  2142. X
  2143. X        rep     movsw                ; load path from si to di
  2144. XIFNDEF NOSPLIT
  2145. X        mov    di, OFFSET filestring
  2146. X        mov    al,0
  2147. X        mov    cx,MAXNAMESIZE
  2148. X        cld
  2149. X        repne    scasb            ; search null for end of string
  2150. X
  2151. X        sub    cx,MAXNAMESIZE
  2152. X        neg    cx
  2153. X        mov    bx,cx
  2154. X
  2155. X        cmp    cx,MAXNAMESIZE
  2156. X        je    checkslash
  2157. X
  2158. X        dec    bx            ; keep string length
  2159. X        dec    di            ; cause were past null now
  2160. X
  2161. X        cmp    bx,7
  2162. X        jle    patherr            ; "C:\.EXE" = 7
  2163. Xcheckslash:
  2164. X        mov    ax,DOSGETSWITCH        ; divine switchar
  2165. X        int    DOS            ; it influences the path
  2166. X
  2167. X        mov    al,'\'            ; if swichar = '/' pathsep = '\'
  2168. X        cmp    dl,'/'
  2169. X        je    searchslash    
  2170. X        mov    al,'/'            ; else pathsep = '/'
  2171. Xsearchslash:
  2172. X        std
  2173. X        repne    scasb            ; search back for '\'
  2174. X        cld
  2175. X
  2176. X        mov    dx,bx
  2177. X        sub    dx,cx            ; keep file name length
  2178. X        dec    dx
  2179. X
  2180. X        mov    cx,0            ; reset for upcoming loop
  2181. X        mov    pathlen,bx        ; hold these for recall
  2182. X        mov    namelen,dx
  2183. X        cmp    dx,12            ; "LONGNAME.EXE" = 12
  2184. X        jle    openroot        ; Path name too long?
  2185. Xpatherr:
  2186. X        mov    al,NAMERR        ; real problems here.
  2187. X        jmp    putserr
  2188. Xopenroot:
  2189. XENDIF
  2190. X        mov    ax,cs
  2191. X        mov    ds,ax            ; set ds to code
  2192. X
  2193. X        mov    dx, OFFSET filestring    ; open root code
  2194. X        mov    al,0            ; access code
  2195. X        mov    ah,DOSOPEN
  2196. X        int    DOS            ; open sez me
  2197. X        jnc    dontdie
  2198. X
  2199. X        mov    al,FILEERR        ; can't open root
  2200. X        jmp    putserr
  2201. Xdontdie:
  2202. X        mov    ovlfilhdl[0],ax        ; save handle in array
  2203. XIFNDEF NOSPLIT
  2204. X        cmp    namelen,11        ; Max sized exe name (8.3)?
  2205. X        jg    bigfilename        ; if not
  2206. X        inc    pathlen            ; add one to path length
  2207. X        inc    namelen
  2208. Xbigfilename:
  2209. X        mov    di,OFFSET filestring    ; es is still code
  2210. X        add    di,pathlen
  2211. X        sub    di,5            ; append
  2212. X        mov    si,OFFSET ovlext    ; wildcard extension
  2213. X        mov    cx,6            ; and null
  2214. X        rep    movsb            ; to filestring
  2215. X
  2216. X        mov    cx,0            ; Match "normal" files
  2217. X        mov    dx,OFFSET filestring
  2218. X        mov    ah,DOSSEARCH
  2219. X        int    DOS            ; Set DTA with Wildcard.
  2220. X        jc    aok            ; Not a single match
  2221. X        mov    cx,MAXFILES        ; set upcoming loop
  2222. X        mov    dx,namelen
  2223. X        sub    pathlen,dx        ; shorten absolute path
  2224. Xopenloop:
  2225. X        push    cx
  2226. X        mov    bx,pathlen
  2227. X        mov    di,OFFSET filestring    ; es is still in code
  2228. X        add    di,bx
  2229. X        mov    si,OFFSET ovldta.file_name
  2230. X        mov    cx,namelen         ; since this *should* be
  2231. X        rep    movsb
  2232. X        pop    cx
  2233. X
  2234. X        mov    dx,OFFSET filestring    ; path to overlay file
  2235. X        mov    al,0            ; access code
  2236. X        mov    ah,DOSOPEN
  2237. X        int    DOS            ; open overlay file
  2238. X        jnc    dontdie2
  2239. Xfileopenerr:
  2240. X        call    itoa
  2241. X
  2242. X        mov    al,OVLERR        ; can't open file!
  2243. X        jmp    putserr
  2244. Xdontdie2:
  2245. X        mov    bx,cx            ; put file number in bx
  2246. X        shl    bx,1            ; 2 * bx for array index
  2247. X        mov    ovlfilhdl[bx],ax    ; save handle in array
  2248. X
  2249. X        mov    ah,DOSNEXTFILE        ; Look for more files
  2250. X        int    DOS
  2251. X        jc    aok
  2252. X
  2253. X        loop    openloop        ; open only 15 overlays
  2254. Xaok:
  2255. X        mov    dx,dtaoffset        ; Time to unset DTA
  2256. X        mov    ds,dtaseg
  2257. X        mov    ah,DOSSETDTA
  2258. X        int    DOS
  2259. XENDIF
  2260. X        pop    es
  2261. X
  2262. X        ret
  2263. X
  2264. Xopenfiles    ENDP
  2265. X
  2266. X;-------------------------------------------------------------------------------
  2267. X
  2268. Xputserr     PROC    NEAR
  2269. X
  2270. X; display error msg, close file, restore int vectors, free mem and return to DOS.
  2271. X
  2272. X        ASSUME    DS:NOTHING,ES:NOTHING
  2273. X
  2274. X        xor    ah,ah
  2275. X        push    ax            ; keep return code for later
  2276. X        push    cs
  2277. X        pop    ds
  2278. X        mov    bx,ax
  2279. X        shl    bx,1
  2280. X        add    bx,OFFSET errortbl
  2281. X        mov    dx,[bx]
  2282. X        cmp    dx,-1
  2283. X        jz    freeints
  2284. X        push    dx
  2285. X        mov    dx,OFFSET msghead
  2286. X        mov    ah,PRINT
  2287. X        int    DOS
  2288. X        pop    dx
  2289. X        mov    ah,PRINT
  2290. X        int    DOS            ; display error msg
  2291. X
  2292. X        mov    ah,PRINT
  2293. X        mov    dx,OFFSET diag
  2294. X        int    DOS
  2295. X        pop    ax
  2296. X        push    ax
  2297. X        call    itoa            ; error number
  2298. X        mov    ah,DOSPUTC
  2299. X        mov    dl,':'
  2300. X        int    DOS
  2301. X        mov    ax,VERSION
  2302. X        call    itoa            ; version number
  2303. X        mov    ah,DOSPUTC
  2304. X        mov    dl,':'
  2305. X        int    DOS
  2306. X        mov    ax,0a000h
  2307. X        sub    ax,ovltblbse        ; conventional memory
  2308. X        call    itoa
  2309. X        mov    ah,DOSPUTC
  2310. X        mov    dl,':'
  2311. X        int    DOS
  2312. X        mov    si,OFFSET emsmemblks
  2313. X        mov    cx,16
  2314. X        xor    ax,ax
  2315. Xemstotlp:
  2316. X        cmp    WORD PTR cs:[si],-1
  2317. X        jz    gotemstot
  2318. X        add    ax,emmframesiz
  2319. X        add    si,2
  2320. X        loop    emstotlp
  2321. Xgotemstot:
  2322. X        call    itoa            ; ems usage in blocks
  2323. X        mov    ah,DOSPUTC
  2324. X        mov    dl,')'
  2325. X        int    DOS
  2326. X
  2327. X        mov    dx,OFFSET msgtail
  2328. X        mov    ah,PRINT
  2329. X        int    DOS
  2330. Xfreeints:
  2331. X        call    rstvectors        ; restore all int vectors
  2332. X
  2333. X        mov    ax,ovltblbse
  2334. X        cmp    ax,-1
  2335. X        jz    freememblks
  2336. X        mov    es,ax
  2337. X        mov    ah,DOSFREE
  2338. X        int    DOS
  2339. Xfreememblks:
  2340. X        mov    cx,16            ; do all allocated mem blocks
  2341. X        mov    si,OFFSET memblks
  2342. Xfreememlp:
  2343. X        mov    ax,cs:[si]        ; get memory blk segment
  2344. X        cmp    ax,-1            ; was one ever allocated?
  2345. X        jz    nxtmemlp        ; nope
  2346. X        mov    es,ax
  2347. X        mov    ah,DOSFREE        ; must free it.
  2348. X        int    DOS
  2349. Xnxtmemlp:
  2350. X        add    si,2
  2351. X        loop    freememlp
  2352. X        mov    cx,16            ; do all allocated ems blocks
  2353. X        mov    si,OFFSET emsmemblks
  2354. Xfreeemsmemlp:
  2355. X        mov    dx,cs:[si]        ; get memory blk segment
  2356. X        cmp    dx,-1            ; was one ever allocated?
  2357. X        jz    nxtemsmemlp        ; nope
  2358. X        mov    ah,EMMFREE        ; must free it.
  2359. X        int    EMM
  2360. Xnxtemsmemlp:
  2361. X        add    si,2
  2362. X        loop    freeemsmemlp
  2363. Xclosefile:
  2364. XIFNDEF NOSPLIT
  2365. X        mov    cx,MAXFILES+1
  2366. Xnextfile:
  2367. X        mov    bx,cx
  2368. X        dec    bx
  2369. X        shl    bx,1
  2370. X        mov    bx,ovlfilhdl[bx]     ; get file handle
  2371. XELSE
  2372. X        mov    bx,ovlfilhdl[0]
  2373. XENDIF
  2374. X        cmp    bx,-1            ; was the file ever opened?
  2375. X        jz    byebye            ; nope
  2376. X        mov    ah,DOSCLOSE        ; close it
  2377. X        int    DOS
  2378. Xbyebye:
  2379. XIFNDEF NOSPLIT
  2380. X        loop    nextfile
  2381. XENDIF
  2382. X        pop    ax            ; return code in al
  2383. X        mov    ah,TERMINATE
  2384. X        int    DOS            ; terminate this process
  2385. X
  2386. Xputserr     ENDP
  2387. X
  2388. X;-------------------------------------------------------------------------------
  2389. X
  2390. Xitoa        PROC    NEAR
  2391. X
  2392. X        push    ax
  2393. X        xchg    ah,al
  2394. X        call    putbyte
  2395. X        pop    ax
  2396. X        jmp    putbyte
  2397. X
  2398. Xitoa        ENDP
  2399. X
  2400. X;-------------------------------------------------------------------------------
  2401. X
  2402. Xputbyte     PROC    NEAR
  2403. X
  2404. X        push    ax
  2405. X        shr    al,1
  2406. X        shr    al,1
  2407. X        shr    al,1
  2408. X        shr    al,1
  2409. X        call    nibble
  2410. X        pop    ax
  2411. X        jmp    nibble
  2412. X
  2413. Xputbyte     ENDP
  2414. X
  2415. X;-------------------------------------------------------------------------------
  2416. X
  2417. Xnibble        PROC    NEAR
  2418. X
  2419. X        push    ax
  2420. X        and    al,0fh
  2421. X        add    al,30h
  2422. X        cmp    al,3ah
  2423. X        jc    nibok
  2424. X        add    al,7
  2425. Xnibok:
  2426. X        push    dx
  2427. X        mov    dl,al
  2428. X        mov    ah,DOSPUTC
  2429. X        int    DOS
  2430. X        pop    dx
  2431. X        pop    ax
  2432. X        ret
  2433. X
  2434. Xnibble        ENDP
  2435. X
  2436. X;-------------------------------------------------------------------------------
  2437. X
  2438. Xsetvectors    PROC    NEAR
  2439. X
  2440. X        push    ds
  2441. X        xor    ax,ax
  2442. X        mov    ds,ax
  2443. X        mov    si,cs:intnum
  2444. X        cli
  2445. X        mov    ax,[si]
  2446. X        mov    WORD PTR cs:oldvec,ax    ; save original vector
  2447. X        mov    ax,[si+2]
  2448. X        mov    WORD PTR cs:oldvec+2,ax
  2449. X        mov    ax,OFFSET ovlmgr    ; point to ovlmgr
  2450. X        mov    [si],ax         ; set int vector
  2451. X        mov    [si+2],cs
  2452. X
  2453. X        mov    si,DOS*4
  2454. X        mov    ax,[si]
  2455. X        mov    WORD PTR cs:oldint21,ax ; save original vector
  2456. X        mov    ax,[si+2]
  2457. X        mov    WORD PTR cs:oldint21+2,ax
  2458. X        mov    ax,OFFSET int21     ; point to new int21
  2459. X        mov    [si],ax         ; set int vector
  2460. X        mov    [si+2],cs
  2461. X        sti
  2462. X        pop    ds
  2463. X        ret
  2464. X
  2465. Xsetvectors    ENDP
  2466. X
  2467. X;-------------------------------------------------------------------------------
  2468. X
  2469. Xrstvectors    PROC    NEAR
  2470. X
  2471. X        push    ds
  2472. X        xor    ax,ax
  2473. X        mov    ds,ax
  2474. X        mov    si,DOS*4
  2475. X        cli
  2476. X        mov    ax,WORD PTR cs:oldint21 ; put back dos vector
  2477. X        cmp    ax,-1
  2478. X        jz    rstvec
  2479. X        mov    [si],ax
  2480. X        mov    ax,WORD PTR cs:oldint21+2
  2481. X        mov    [si+2],ax
  2482. Xrstvec:
  2483. X        mov    si,cs:intnum
  2484. X        mov    ax,WORD PTR cs:oldvec    ; put back ovlmgr vector
  2485. X        cmp    ax,-1
  2486. X        jz    rstdone
  2487. X        mov    [si],ax
  2488. X        mov    ax,WORD PTR cs:oldvec+2
  2489. X        mov    [si+2],ax
  2490. X        sti
  2491. Xrstdone:
  2492. X        pop    ds
  2493. X        ret
  2494. X
  2495. Xrstvectors    ENDP
  2496. X
  2497. Xcode        ENDS
  2498. X
  2499. X        END
  2500. END_OF_FILE
  2501. if test 46506 -ne `wc -c <'sys/msdos/ovlmgr.asm'`; then
  2502.     echo shar: \"'sys/msdos/ovlmgr.asm'\" unpacked with wrong size!
  2503. fi
  2504. # end of 'sys/msdos/ovlmgr.asm'
  2505. fi
  2506. echo shar: End of archive 18 \(of 108\).
  2507. cp /dev/null ark18isdone
  2508. MISSING=""
  2509. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2510. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2511. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2512. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2513. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2514. 101 102 103 104 105 106 107 108 ; do
  2515.     if test ! -f ark${I}isdone ; then
  2516.     MISSING="${MISSING} ${I}"
  2517.     fi
  2518. done
  2519. if test "${MISSING}" = "" ; then
  2520.     echo You have unpacked all 108 archives.
  2521.     echo "Now execute 'rebuild.sh'"
  2522.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2523. else
  2524.     echo You still need to unpack the following archives:
  2525.     echo "        " ${MISSING}
  2526. fi
  2527. ##  End of shell archive.
  2528. exit 0
  2529.