home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume16 / nethack31 / part18 < prev    next >
Internet Message Format  |  1993-02-01  |  60KB

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