     1                                  ;*********************************************************************
     2                                  ;*   OVLMGR.ASM                                                      *
     3                                  ;*   By:            Michael Devore                                   *
     4                                  ;*   Date:          03/12/93                                         *
     5                                  ;*   Version:       2.50                                             *
     6                                  ;*   Assembler:     TASM 2.0                                         *
     7                                  ;*   Environment:   MS-DOS 2.x+                                      *
     8                                  ;*   Copyright 1990-91, Michael E. Devore                            *
     9                                  ;*                                                                   *
    10                                  ;*   overlay manager code                                            *
    11                                  ;*                                                                   *
    12                                  ;*********************************************************************
    13                                  
    14                                  ;TITLE   OVLMGR.ASM
    15                                  ;PAGE    50,80
    16                                  
    17                                  ;*****************************
    18                                  ;* EQUATES                   *
    19                                  ;*****************************
    20                                  
    21                                  STDIN   EQU 0               ; standard input device
    22                                  STDOUT  EQU 1               ; standard output device
    23                                  STDERR  EQU 2               ; standard error device
    24                                  
    25                                  BELL    EQU     7           ; beep the speaker
    26                                  CR      EQU     13          ; carriage return
    27                                  LF      EQU     10          ; line feed
    28                                  FF      EQU     12          ; form feed
    29                                  
    30                                  ;*****************************
    31                                  ;* PUBLICS                   *
    32                                  ;*****************************
    33                                  
    34                                  ; set by /os linker option, used by overlay manager
    35                                  PUBLIC  D.D._ovl_stack
    36                                  
    37                                  ; set by /ol linker option, used by overlay manager
    38                                  PUBLIC  D.D._ovl_max_load
    39                                  
    40                                  ; set by /op linker option, used by overlay manager
    41                                  PUBLIC  D.D._ovl_pool
    42                                  PUBLIC  D.D._ovl_mem_alloc_flag
    43                                  
    44                                  ; set by /r linker option, used by overlay manager
    45                                  PUBLIC  D.D._ovl_reload_flag
    46                                  
    47                                  ; set by /cla linker option, used by overlay manager
    48                                  PUBLIC  D.D._ovl_clarion_flag
    49                                  
    50                                  ; set by /oi linker option, used by overlay manager
    51                                  PUBLIC  D.D._ovl_internal_flag
    52                                  
    53                                  ; set by /ox linker options, used by overlay manager
    54                                  PUBLIC  D.D._ovl_ems_pool_flag
    55                                  
    56                                  ; name of overlay file, including .OVL extension, computed by linker
    57                                  PUBLIC  D.D._ovl_filename
    58                                  PUBLIC  _ovlmgr_overlay_filename
    59                                  
    60                                  ; /ox e-var setting
    61                                  PUBLIC  D.D._ovl_ox_evar
    62                                  
    63                                  ; size in paragraphs of largest overlay rounded to 1K page, computed by linker
    64                                  PUBLIC  D.D._ovl_min_alloc
    65                                  
    66                                  ; main entry point of program, computed by linker
    67                                  PUBLIC  D.D._main_entry
    68                                  
    69                                  ; segment of lookup table for overlay target addresses, computed by linker
    70                                  PUBLIC  D.D._ovl_lookup_table
    71                                  
    72                                  ; segment of indirect call table for overlay target addresses, computed by linker
    73                                  PUBLIC  D.D._ovl_ind_call_table
    74                                  
    75                                  ; address used by linker for initial entry
    76                                  PUBLIC  D.D._ovl_init_entry
    77                                  
    78                                  ; address used by linker to vector calls to overlaid publics
    79                                  PUBLIC D.D._ovl_vector
    80                                  
    81                                  ; address used by link to return vectored calls
    82                                  PUBLIC D.D._ovl_ret
    83                                  
    84                                  ; size in paragraphs of executable program
    85                                  PUBLIC  D.D._min_prog_size
    86                                  
    87                                  ; addresses used by link for indirect calls
    88                                  PUBLIC  D.D._ovl_ind_2ovl_ent
    89                                  
    90                                  ; address used by link for overlaid target segment fixups
    91                                  PUBLIC  D.D._ovl_seg_call_table
    92                                  PUBLIC  D.D._ovl_seg_call_entry
    93                                  
    94                                  ; routine to call to close overlay file
    95                                  PUBLIC  _ovlmgr_close_ovl_file
    96                                  
    97                                  ; routine to call to open overlay file
    98                                  PUBLIC  _ovlmgr_open_ovl_file
    99                                  
   100                                  ; routine to free overlay manager acquired EMS
   101                                  PUBLIC  _ovlmgr_free_ems,_om_fr_ems
   102                                  
   103                                  ; /ort setting
   104                                  PUBLIC  D.D._ovl_ort
   105                                  
   106                                  ; /orp setting
   107                                  PUBLIC  D.D._ovl_orp
   108                                  
   109                                  ; /ohp setting
   110                                  PUBLIC	D.D._ovl_ohp,D.D._ohp_size,D.D._ohp_flag
   111                                  
   112                                  ; /oht setting
   113                                  PUBLIC	D.D._ovl_oht,D.D._oht_size,D.D._oht_flag
   114                                  
   115                                  ; /ou setting
   116                                  PUBLIC	D.D._ovl_umb
   117                                  
   118                                  ; /ohp3 EMS 3.0 compatibility settting
   119                                  PUBLIC	D.D._ems3_flag
   120                                  
   121                                  ; size of overlay file in kilobytes (used for file stashing)
   122                                  PUBLIC	D.D._ovl_file_size
   123                                  
   124                                  ; locations referenced by profiler
   125                                  PUBLIC D.D._ovl_jump_target, D.D._ovl_destination_id
   126                                  PUBLIC D.D._ovl_call_target, D.D._ovl_source_id
   127                                  PUBLIC D.D._ovl_load_start, D.D._ovl_load_end
   128                                  PUBLIC D.D._ovl_load_count, D.D._ovl_reload_count
   129                                  PUBLIC D.D._ovl_in_manager, D.D._ovl_is_calling
   130                                  
   131                                  ; code addresses trapped by profiler
   132                                  PUBLIC D.D._ovl_prof_call, D.D._ovl_prof_return
   133                                  PUBLIC D.D._ovl_load_overlay
   134                                  
   135                                  ;*****************************
   136                                  ;* STACK                     *
   137                                  ;*****************************
   138                                  
   139                                  section D.D._OVL_MGR_STACK align=16 PRIVATE class=D.D._OVL_MANAGER
   140 00000000 <res 140h>                  DW  160 DUP (?)
   141                                  D.D._ovl_mgr_stack_end    equ   $
   142                                  ; (no prior section) ; D.D._ovl_mgr_stack    ENDS
   143                                  
   144                                  ;*****************************
   145                                  ;* DATA                      *
   146                                  ;*****************************
   147                                  
   148                                  section D.D._OVL_DATA align=16 PRIVATE class=D.D._OVL_MANAGER
   149                                  
   150                                  ; constant data
   151 00000000 0D0A464154414C2044-     dos_err_text    DB  CR,LF,'FATAL DOS Error, Code '
   151 00000009 4F53204572726F722C-
   151 00000012 20436F646520       
   152 00000018 0D0A464154414C204F-     ovl_err_text    DB  CR,LF,'FATAL Overlay Manager Error, Code '
   152 00000021 7665726C6179204D61-
   152 0000002A 6E6167657220457272-
   152 00000033 6F722C20436F646520 
   153 0000003C 3030680D0A              code_text       DB  '00h',CR,LF
   154 00000041 504154483D              pathtext        DB  'PATH='
   155                                  
   156                                  pointer_start	EQU	$
   157                                  _ovlmgr_overlay_filename    EQU $
   158 00000046 000000000000000000-     D.D._ovl_filename DB  128 DUP (0) ; overlay file name
   158 0000004F 000000000000000000-
   158 00000058 000000000000000000-
   158 00000061 000000000000000000-
   158 0000006A 000000000000000000-
   158 00000073 000000000000000000-
   158 0000007C 000000000000000000-
   158 00000085 000000000000000000-
   158 0000008E 000000000000000000-
   158 00000097 000000000000000000-
   158 000000A0 000000000000000000-
   158 000000A9 000000000000000000-
   158 000000B2 000000000000000000-
   158 000000BB 000000000000000000-
   158 000000C4 0000               
   159 000000C6 0D05045631              				DB 	13,5,4,'V','1'	; signature bytes
   160                                  
   161 000000CB AE00                    				DW	(OFFSET D.D._ovl_pool)-pointer_start
   162 000000CD BC00                    				DW	(OFFSET D.D._ovl_mem_alloc_flag)-pointer_start
   163 000000CF 3809                    				DW	(OFFSET D.D._ovl_ohp)-pointer_start
   164 000000D1 4009                    				DW	(OFFSET D.D._ohp_size)-pointer_start
   165 000000D3 3A09                    				DW	(OFFSET D.D._ohp_flag)-pointer_start
   166 000000D5 3D09                    				DW	(OFFSET D.D._ems3_flag)-pointer_start
   167 000000D7 3909                    				DW	(OFFSET D.D._ovl_oht)-pointer_start
   168 000000D9 4209                    				DW	(OFFSET D.D._oht_size)-pointer_start
   169 000000DB 3B09                    				DW	(OFFSET D.D._oht_flag)-pointer_start
   170 000000DD 3C09                    				DW	(OFFSET D.D._ovl_umb)-pointer_start
   171 000000DF B800                    				DW	(OFFSET D.D._ovl_stack)-pointer_start
   172 000000E1 B600                    				DW	(OFFSET D.D._ovl_max_load)-pointer_start
   173 000000E3 3709                    				DW	(OFFSET D.D._ovl_orp)-pointer_start
   174 000000E5 3609                    				DW	(OFFSET D.D._ovl_ort)-pointer_start
   175 000000E7 0000                    				DW	(OFFSET D.D._ovl_filename)-pointer_start
   176 000000E9 3509                    				DW	(OFFSET D.D._ovl_ems_pool_flag)-pointer_start
   177 000000EB 1509                    				DW	(OFFSET D.D._ovl_ox_evar)-pointer_start
   178                                  
   179 000000ED 00                      EVEN
   180                                  
   181                                  ; modifiable data
   182                                  
   183                                  ; values set by linker
   184                                  ;***_ovlmgr_overlay_filename    EQU $
   185                                  ;***$$_ovl_filename DB  128 DUP (0) ; overlay file name
   186 000000EE ????                    D.D._min_prog_size    DW  ?   ; minimum program size in paragraphs
   187 000000F0 ????                    D.D._ovl_ind_call_table DW  ? ; segment of indirect call table
   188 000000F2 ????                    D.D._ovl_seg_call_table DW  ? ; segment of segment fixup jump table
   189                                  
   190 000000F4 00400200                D.D._ovl_pool DD  147456      ; overlay pool or free memory size
   191 000000F8 01000000                D.D._ovl_lru_counter  DD  1   ; least recent used counter for overlay swap priority
   192                                  
   193 000000FC 6000                    D.D._ovl_max_load DW  96      ; maximum number of loaded overlays
   194 000000FE 0008                    D.D._ovl_stack    DW  2048    ; overlay stack size
   195 00000100 0004                    D.D._ovl_min_alloc    DW  1024    ; size in paragraphs of largest overlay
   196                                  
   197 00000102 00                      D.D._ovl_mem_alloc_flag   DB  0   ; nonzero if $$_ovl_pool holds overlay pool size, zero if free memory
   198 00000103 00                      EVEN                        ; re-align to word boundary
   199                                  
   200                                  ; computed by overlay initialization code
   201 00000104 ????                    D.D._ovl_array_start  DW  ?   ; start of overlay load array
   202 00000106 ????                    D.D._ovl_amt_alloc    DW  ?   ; amount of memory allocated to overlays in paragraphs
   203 00000108 ????                    D.D._ovl_amt_512      DW  ?   ; amount of memory allocated to overlays in 512 blocks
   204 0000010A ????                    D.D._ovl_filepos      DW  ?   ; segment of table of overlay file positions in .OVL file
   205                                  
   206                                  ; used and modified by overlay manager code
   207 0000010C 000000000000000000-     D.D._ovl_tfile        DB  13 DUP (0)  ; temporary storage for file name if not found in current directory
   207 00000115 00000000           
   208 00000119 00                      EVEN
   209 0000011A ????????                D.D._ovl_sysinfo_off  DD  ?   ; offset in OVL file to system information
   210 0000011E ????????                D.D._ovl_file_offset  DD  ?   ; offset in OVL to current overlay file
   211 00000122 0000                    D.D._ovl_loaded_count DW  0   ; count of loaded overlays
   212 00000124 0000                    D.D._ovl_file_handle  DW  0   ; overlay file handle
   213                                  
   214 00000126 ????                    D.D._ovl_filepos_size DW  ?   ; size of file position table, # of entries, changed to # of bytes
   215 00000128 ????                    D.D._ovl_total_count  DW  ?   ; total number of overlays
   216                                  
   217 0000012A ????????????            D.D._ovl_temp_buff    DW  3 DUP (?)   ; temporary buffer when reading info for internal overlays
   218                                  
   219                                  D.D._ovl_file_header  EQU $   ; first 5 words (10 bytes) of overlay file header go here
   220 00000130 ????                        ofh_ovl_number  DW  ?   ; number of overlay
   221 00000132 ????                        ofh_ovl_offset  DW  ?   ; Offset to overlay code
   222 00000134 ????                        ofh_ovl_size    DW  ?   ; Overlay code size in paragraphs
   223 00000136 ????                        ofh_near_vector DW  ?   ; Offset to near vector routine in segment
   224 00000138 ????                        ofh_reloc_count DW  ?   ; Relocation entry count
   225                                  
   226 0000013A ????????                D.D._ovl_rel_pos  DD  ?       ; relocation table file position
   227 0000013E ????                    D.D._ovl_load_seg DW  ?       ; current overlay load segment
   228                                  
   229 00000140 ????                    D.D._ovl_swap_count   DW  ?   ; number of overlays swapped out by proposed overlay load
   230                                  ;***$$_ovl_swap_active  DW  ?   ; number of active overlays swapped out by proposed overlay load
   231 00000142 ????                    D.D._ovl_best_load    DW  ?   ; the best of the proposed overlay loads, based on LRU and swap count
   232 00000144 ????                    D.D._ovl_best_count   DW  ?   ; best of proposed overlay load, number of overlays swapped out
   233                                  ;***$$_ovl_best_active  DW  ?   ; best of proposed overlay load, number of active overlays swapped
   234                                  
   235 00000146 ????????                D.D._ovl_highest_lru  DD  ?   ; highest LRU counter of overlays swapped out by proposed overlay load
   236 0000014A ????????                D.D._ovl_hi_best_lru  DD  ?   ; best of proposed overlay load, highest LRU counter
   237                                  ;***$$_ovl_hi_act_lru   DD  ?   ; highest LRU counter of active overlays swapped (for /r option)
   238                                  ;***$$_ovl_hi_best_act  DD  ?   ; best of proposed overlay load, highest LRU counter of actives swapped (/r option)
   239                                  
   240 0000014E ????                    D.D._ovl_activity     DW  ?   ; activity level of overlay (0 if not active)
   241                                  
   242 00000150 ????                    swapped_lru_high    DW  ?   ; swapped out overlay LRU high word
   243 00000152 ????                    swapped_lru_low     DW  ?   ; swapped out overlay LRU low word
   244                                  
   245 00000154 ????                    ovl_act_size        DW  ?   ; proposed overlay load size
   246 00000156 ????                    ovl_best_size       DW  ?   ; best of proposed overlay load sizes
   247 00000158 ????                    check_array_size    DW  ?   ; size of check array in bytes
   248 0000015A 00                      dos5_umb_flag	DB	0		; nonzero if DOS 5 UMB's used for overlay pool
   249                                  
   250                                  ems_trans_block	LABEL	BYTE
   251                                  ; relocation table of overlay file (1K max each time, 512 entries)
   252                                  D.D._ovl_rel_table    EQU $
   253 0000015B <res 400h>                  DB  1024 DUP (?)
   254 0000055B <res 400h>                  DB  1024 DUP (?)
   255                                  
   256                                  ; modifiable
   257 0000095B 000000000000000000-     D.D._ovl_ox_evar  DB  32 DUP (0)  ; e-var for /ox option
   257 00000964 000000000000000000-
   257 0000096D 000000000000000000-
   257 00000976 0000000000         
   258 0000097B 00                      D.D._ovl_ems_pool_flag    DB  0   ; nonzero if overlay pool uses EMS
   259 0000097C 00                      D.D._ovl_ort  DB  0           ; nonzero if /ort setting used
   260 0000097D 00                      D.D._ovl_orp  DB  0           ; nonzero if /orp setting used
   261 0000097E 00                      D.D._ovl_ohp	DB	0			; nonzero if /ohp setting
   262 0000097F 00                      D.D._ovl_oht	DB	0			; nonzero if /oht setting
   263 00000980 00                      D.D._ohp_flag	DB	0			; nonzero if /ohp allocate to amount flag set
   264 00000981 00                      D.D._oht_flag	DB	0			; nonzero if /oht allocate to amount flag set
   265 00000982 00                      D.D._ovl_umb	DB	0			; nonzero if /ou setting used
   266 00000983 00                      D.D._ems3_flag	DB	0		; nonzero if /ohp3 EMS 3.0 compatibility setting used
   267                                  
   268 00000984 ??                      info_from_emsxms_flag	DB	?	; nonzero if current overlay stashed in EMS/XMS, 80h-XMS, 40h-EMS
   269 00000985 ??                      emsxms_stash_flag	DB	?	; nonzero if stashing current overlay to EMS/XMS, 80h-XMs,40h-EMS
   270                                  EVEN
   271 00000986 0000                    D.D._ohp_size	DW	0     		; /ohp size in K
   272 00000988 0000                    D.D._oht_size	DW	0			; /oht size in K
   273 0000098A 0000                    D.D._ovl_file_size	DW	0	; overlay file size in K
   274 0000098C ????                    D.D._ovl_ox_handle	DW  ?   ; handle of allocated EMS for /ox
   275 0000098E ????                    D.D._ovl_ems_base     DW  ?   ; page frame base of EMS
   276 00000990 454D4D585858583000      emmname     DB  'EMMXXXX0',0
   277 00000999 000000000000000000-     xe_table    DW  256 DUP (0) ; XMS/EMS active overlay stash table
   277 000009A2 000000000000000000-
   277 000009AB 000000000000000000-
   277 000009B4 000000000000000000-
   277 000009BD 000000000000000000-
   277 000009C6 000000000000000000-
   277 000009CF 000000000000000000-
   277 000009D8 000000000000000000-
   277 000009E1 000000000000000000-
   277 000009EA 000000000000000000-
   277 000009F3 000000000000000000-
   277 000009FC 000000000000000000-
   277 00000A05 000000000000000000-
   277 00000A0E 000000000000000000-
   277 00000A17 000000000000000000-
   277 00000A20 000000000000000000-
   277 00000A29 000000000000000000-
   277 00000A32 000000000000000000-
   277 00000A3B 000000000000000000-
   277 00000A44 000000000000000000-
   277 00000A4D 000000000000000000-
   277 00000A56 000000000000000000-
   277 00000A5F 000000000000000000-
   277 00000A68 000000000000000000-
   277 00000A71 000000000000000000-
   277 00000A7A 000000000000000000-
   277 00000A83 000000000000000000-
   277 00000A8C 000000000000000000-
   277 00000A95 000000000000000000-
   277 00000A9E 000000000000000000-
   277 00000AA7 000000000000000000-
   277 00000AB0 000000000000000000-
   277 00000AB9 000000000000000000-
   277 00000AC2 000000000000000000-
   277 00000ACB 000000000000000000-
   277 00000AD4 000000000000000000-
   277 00000ADD 000000000000000000-
   277 00000AE6 000000000000000000-
   277 00000AEF 000000000000000000-
   277 00000AF8 000000000000000000-
   277 00000B01 000000000000000000-
   277 00000B0A 000000000000000000-
   277 00000B13 000000000000000000-
   277 00000B1C 000000000000000000-
   277 00000B25 000000000000000000-
   277 00000B2E 000000000000000000-
   277 00000B37 000000000000000000-
   277 00000B40 000000000000000000-
   277 00000B49 000000000000000000-
   277 00000B52 000000000000000000-
   277 00000B5B 000000000000000000-
   277 00000B64 000000000000000000-
   277 00000B6D 000000000000000000-
   277 00000B76 000000000000000000-
   277 00000B7F 000000000000000000-
   277 00000B88 000000000000000000-
   277 00000B91 0000000000000000   
   278 00000B99 ????                    orport_handle   DW  ?       ; handle for XMS/EMS active overlay stashing
   279 00000B9B ????                    ohpoht_handle   DW  ?       ; handle for XMS/EMS overlay file stashing
   280 00000B9D ????????                xms_addr    DD  ?           ; XMS entry point address
   281 00000BA1 ????                    umb_avail	DW	?			; size of largest available UMB block in paras
   282 00000BA3 ????????                emsxms_free	DD	?			; bytes of EMS/XMS free for file stashing
   283 00000BA7 00000000                emsxms_offset	DD	0		; offset to current stash position in EMS/XMS
   284                                  
   285                                  EMB_STRUC   STRUC
   286 00000000 ????????                    es_len  DD  ?           ; length of block in bytes
   287 00000004 ????                        es_src_handle   DW  ?   ; source EMB handle
   288 00000006 ????????                    es_src_offset   DD  ?   ; source offset
   289 0000000A ????                        es_dest_handle  DW  ?   ; destination EMB handle
   290 0000000C ????????                    es_dest_offset  DD  ?   ; destination offset
   291                                  EMB_STRUC   ENDS
   292                                  emb: ; NASM structure instance
   293                                  EMB_STRUC_size equ EMB_STRUC_struc_size	; NASM port equate
   294                                  istruc EMB_STRUC
   295 00000BAB ??<rep 10h>             iend
   296                                  
   297                                  OHTBUFF_STRUC	STRUC
   298 00000000 ????????                    os_len  DD  ?           ; length of block in bytes
   299 00000004 ????                        os_src_handle   DW  ?   ; source EMB handle
   300 00000006 ????????                    os_src_offset   DD  ?   ; source offset
   301 0000000A ????                        os_dest_handle  DW  ?   ; destination EMB handle
   302 0000000C ????????                    os_dest_offset  DD  ?   ; destination offset
   303                                  OHTBUFF_STRUC	ENDS
   304                                  ohtbuff: ; NASM structure instance
   305                                  OHTBUFF_STRUC_size equ OHTBUFF_STRUC_struc_size	; NASM port equate
   306                                  istruc OHTBUFF_STRUC
   307 00000BBB ??<rep 10h>             iend
   308                                  
   309                                  XBUFF_STRUC STRUC
   310 00000000 ????????                    xs_len  DD  ?           ; length of block in bytes
   311 00000004 ??                          xs_stype    DB  ?       ; source type (0==conventional, 1==expanded)
   312 00000005 ????                        xs_shandle  DW  ?       ; source handle
   313 00000007 ????                        xs_soffset  DW  ?       ; source offset
   314 00000009 ????                        xs_ssegpage DW  ?       ; source memory segment or logical page number
   315 0000000B ??                          xs_dtype    DB  ?       ; destination type (0==conventional, 1==expanded)
   316 0000000C ????                        xs_dhandle  DW  ?       ; destination handle
   317 0000000E ????                        xs_doffset  DW  ?       ; destination offset
   318 00000010 ????                        xs_dsegpage DW  ?       ; destination memory segment or logical page number
   319                                  XBUFF_STRUC	ENDS
   320                                  xbuff: ; NASM structure instance
   321                                  XBUFF_STRUC_size equ XBUFF_STRUC_struc_size	; NASM port equate
   322                                  istruc XBUFF_STRUC
   323 00000BCB ??<rep 12h>             iend
   324                                  
   325                                  OHPBUFF_STRUC	STRUC
   326 00000000 ????????                    os_len  DD  ?           ; length of block in bytes
   327 00000004 ??                          os_stype    DB  ?       ; source type (0==conventional, 1==expanded)
   328 00000005 ????                        os_shandle  DW  ?       ; source handle
   329 00000007 ????                        os_soffset  DW  ?       ; source offset
   330 00000009 ????                        os_ssegpage DW  ?       ; source memory segment or logical page number
   331 0000000B ??                          os_dtype    DB  ?       ; destination type (0==conventional, 1==expanded)
   332 0000000C ????                        os_dhandle  DW  ?       ; destination handle
   333 0000000E ????                        os_doffset  DW  ?       ; destination offset
   334 00000010 ????                        os_dsegpage DW  ?       ; destination memory segment or logical page number
   335                                  OHPBUFF_STRUC	ENDS
   336                                  ohpbuff: ; NASM structure instance
   337                                  OHPBUFF_STRUC_size equ OHPBUFF_STRUC_struc_size	; NASM port equate
   338                                  istruc OHPBUFF_STRUC
   339 00000BDD ??<rep 12h>             iend
   340                                  
   341                                  ; profiler performance data
   342 00000BEF 00000000                D.D._ovl_load_count   DD  0   ; number of overlay loads
   343 00000BF3 00000000                D.D._ovl_reload_count DD  0   ; number of overlay reloads
   344                                  
   345 00000BF7 ????                    check_array DW  ?           ; address of array to check for loaded overlays
   346                                  
   347                                  ; (no prior section) ; D.D._ovl_data ENDS
   348                                  
   349                                  GROUP DGROUP
   350                                  common _ovlmgr_error_vector 4:NEAR  ; installed error handler
   351                                  
   352                                  ;*****************************
   353                                  ;* CODE                      *
   354                                  ;*****************************
   355                                  
   356                                  section D.D._OVL_CODE align=16 PRIVATE class=D.D._OVL_MANAGER
   357                                  
   358                                      ASSUME  cs:D.D._ovl_code,ds:D.D._ovl_data,ss:D.D._ovl_mgr_stack
   359                                  
   360                                  ;*****************************
   361                                  ;* CODE SEGMENT DATA         *
   362                                  ;*****************************
   363                                  
   364                                  ; from procedure $$_ovl_init
   365 00000000 ????                    prog_sp_store   DW  ?
   366 00000002 ????                    prog_ss_store   DW  ?
   367 00000004 ????                    D.D._ovl_stack_ptr    DW  ?   ; current stack pointer for overlay manager
   368 00000006 ????                    D.D._ovl_stack_start  DW  ?   ; start of stack block
   369 00000008 ????                    D.D._ovl_mgr_stack_ptr    DW  ?   ; current stack pointer for internal overlay manager stack
   370 0000000A ????                    D.D._ovl_load_start   DW  ?   ; start of overlay load area
   371 0000000C ????                    D.D._ovl_load_end     DW  ?   ; end of overlay load area
   372                                  
   373                                  ; from procedure $$_ovl_mgr_entry
   374                                  D.D._ovl_source_id LABEL word
   375 0000000E ????                    source_id   DW  ?
   376                                  D.D._ovl_destination_id LABEL word
   377 00000010 ????                    destination_id  DW  ?
   378                                  D.D._ovl_call_target LABEL dword
   379 00000012 ????                    call_offset DW  ?
   380 00000014 ????                    call_segment    DW  ?
   381 00000016 ????                    ax_store    DW  ?
   382 00000018 ????                    bx_store    DW  ?
   383 0000001A ????                    cx_store    DW  ?
   384 0000001C ????                    dx_store    DW  ?
   385 0000001E ????                    si_store    DW  ?
   386 00000020 ????                    ds_store    DW  ?
   387 00000022 ????                    flag_store  DW  ?
   388                                  D.D._ovl_jump_target LABEL dword
   389 00000024 ????                    jump_offset DW  ?
   390 00000026 ????                    jump_segment    DW  ?
   391 00000028 ????                    nearv_offset    DW  ?
   392                                  
   393 0000002A ????                    prog_psp    DW  ?           ; beginning PSP value
   394                                  
   395 0000002C ????????                D.D._main_entry   DD  ?       ; main entry point into program, needs to be fixed up
   396 00000030 ????                    D.D._ovl_lookup_table DW  ?   ; segment of lookup table, needs to be fixed up
   397                                  
   398 00000032 ????                    D.D._ovl_stackcount  DW   ?   ; count of active overlays swapped out to be reloaded upon return
   399 00000034 ??                      D.D._ovl_reload_flag  DB  ?   ; nonzero if must reload active overlays that are swapped out
   400 00000035 90                      align 2, nop
   401                                  D.D._ovl_is_calling   LABEL byte
   402 00000036 ??                      is_calling_ovl      DB  ?   ; nonzero if calling overlay, zero if returning from overlay
   403 00000037 90                      align 2, nop
   404 00000038 ??                      D.D._ovl_clarion_flag DB  ?   ; nonzero if clarion overlay mode in effect
   405 00000039 90                      align 2, nop
   406 0000003A ??                      D.D._ovl_internal_flag    DB  ?   ; nonzero if internal overlays
   407 0000003B 90                      align 2, nop
   408 0000003C 00                      D.D._ovl_in_manager   DB  0   ; nonzero if in overlay manager (for profiler)
   409 0000003D 90                      align 2, nop
   410 0000003E ????????                psp_terminate   DD  ?       ; termination vector from PSP
   411 00000042 ????                    bp_store    DW  ?
   412 00000044 0000                    last_access_slot    DW  0   ; array slot address of last accessed overlay
   413                                  
   414                                  ;*****************************
   415                                  ;* $$_OVL_INIT               *
   416                                  ;*****************************
   417                                  
   418                                  ; initial code performed when executable linked with overlays
   419                                  ; destroys ax,bx,cx,dx,di,si
   420                                  
   421                                  D.D._ovl_init PROC    FAR
   422                                  
   423                                  D.D._ovl_init_entry:
   424 00000046 8CD0                        mov ax,ss
   425 00000048 89E3                        mov bx,sp               ; get stack entry values
   426 0000004A 2EA3[0200]                  mov [cs:prog_ss_store],ax
   427 0000004E 2E891E[0000]                mov [cs:prog_sp_store],bx ; save them
   428                                  
   429 00000053 BB[4001]                    mov bx,OFFSET D.D._ovl_mgr_stack_end
   430 00000056 B8[ssss]                    mov ax,SEG D.D._ovl_mgr_stack_end
   431 00000059 FA                          cli                     ; shut off interrupts while stack is set
   432 0000005A 8ED0                        mov ss,ax
   433 0000005C 89DC                        mov sp,bx               ; set internal stack
   434 0000005E FB                          sti                     ; turn interrupts back on
   435                                  
   436 0000005F 1E                          push    ds              ; save data segment entry value
   437                                  D.D._ovl_data equ D.D._OVL_DATA	; NASM port equate
   438 00000060 B8[ssss]                    mov ax,D.D._ovl_data
   439 00000063 8ED8                        mov ds,ax               ; ds -> overlay manager data
   440 00000065 8CC0                        mov ax,es               ; get PSP value
   441 00000067 2EA3[2A00]                  mov [cs:prog_psp],ax      ; save to memory variable
   442 0000006B 83C010                      add ax,10h              ; bump to program load segment
   443 0000006E 2E0106[2E00]                add WORD PTR [cs:D.D._main_entry+2],ax  ; fixup entry address
   444 00000073 2E0106[3000]                add [cs:D.D._ovl_lookup_table],ax   ; fixup lookup table address
   445                                  
   446                                  ; check for existence of .OVL file, either in current directory or environment PATH
   447                                  err_retry1:
   448 00000078 BA[4600]                    mov dx,OFFSET D.D._ovl_filename   ; ds:dx -> .OVL file spec
   449 0000007B B80043                      mov ax,4300h            ; get file attributes (check for file existence)
   450 0000007E CD21                        int 21h
   451 00000080 7317                        jnc init_1              ; file found okay
   452 00000082 83F802                      cmp ax,2                ; check for file not found error
   453 00000085 740F                        je  scan_path           ; yes, scan the path for .OVL file
   454 00000087 83F803                      cmp ax,3                ; check if path not found or file doesn't exist error
   455 0000008A 740A                        je  scan_path           ; yes
   456 0000008C 83F805                      cmp ax,5                ; check for access denied (not in current directory)
   457 0000008F 7405                        je  scan_path
   458                                  
   459 00000091 E80412                      call    NEAR PTR D.D._ovl_dos_error   ; no, dos error
   460 00000094 EBE2                        jmp SHORT err_retry1    ; try again
   461                                  
   462                                  ; .OVL file not found in current directory, search PATH environment string
   463                                  scan_path:
   464 00000096 E82503                      call    D.D._ovl_find_ovl_file
   465                                  
   466                                  init_1:
   467                                  ; adjust the memory allocated to the program, using the top of memory
   468                                  ; pointer at PSP:2 and the PSP value
   469 00000099 26A10200                    mov ax,[es:2]           ; get top of allocated memory
   470 0000009D 8CC3                        mov bx,es
   471 0000009F 29D8                        sub ax,bx               ; get difference between top of memory and PSP
   472 000000A1 89C2                        mov dx,ax               ; dx holds original memory allocation amount
   473 000000A3 83E810                      sub ax,10h              ; subtract off PSP to get all memory allocated to program
   474 000000A6 2B06[EE00]                  sub ax,[D.D._min_prog_size] ; get memory in excess of amount need for program in ax
   475                                  
   476 000000AA 8B36[FE00]                  mov si,[D.D._ovl_stack]     ; get size of stack to allocate
   477 000000AE D1EE                        shr si,1                ; convert to paragraphs
   478 000000B0 D1EE                        shr si,1
   479 000000B2 D1EE                        shr si,1
   480 000000B4 D1EE                        shr si,1
   481 000000B6 39F0                        cmp ax,si               ; make sure excess memory is equal to or greater than stack allocation
   482 000000B8 7306                        jae init_1a             ; yes
   483                                  
   484                                  ; out of memory error, not enough memory for overlay setup
   485                                  init_memerr:
   486 000000BA B80800                      mov ax,8                ; force out of memory error
   487 000000BD E8D811                      call    NEAR PTR D.D._ovl_dos_error   ; no return
   488                                  
   489                                  init_1a:
   490 000000C0 29F0                        sub ax,si               ; ax holds free memory paragraphs after stack reduction
   491 000000C2 8B3E[FC00]                  mov di,[D.D._ovl_max_load]  ; get size of array to load (already in paragraphs)
   492 000000C6 29F8                        sub ax,di               ; ax holds free memory paragraphs after array reduction
   493 000000C8 72F0                        jc  init_memerr         ; out of memory
   494                                  
   495 000000CA E8F401                      call    get_ovl_total   ; open overlay file, get total number of overlays, compute memory allocation
   496                                  
   497                                  ; allow 10h paragraphs play for allocation adjustment overhead (at least 4 needed)
   498 000000CD 83F810                      cmp ax,10h
   499                                  
   500                                  to_init_memerr:
   501 000000D0 72E8                        jb  init_memerr         ; not enough memory
   502 000000D2 83E810                      sub ax,10h              ; back off overhead adjustment
   503                                  
   504 000000D5 8B0E[F500]                  mov cx,WORD PTR [D.D._ovl_pool+1] ; get 512 byte blocks*2
   505 000000D9 83C10F                      add cx,15               ; round up
   506 000000DC D1E9                        shr cx,1
   507 000000DE D1E9                        shr cx,1
   508 000000E0 D1E9                        shr cx,1
   509 000000E2 D1E9                        shr cx,1                ; get paragraph count
   510 000000E4 29C8                        sub ax,cx               ; subtract off 2 bytes/512 byte page
   511 000000E6 72D2                        jc  init_memerr         ; out of memory
   512                                  
   513                                  ; check if UMB specified, if so, see if XMS available get largest UMB
   514 000000E8 803E[8209]00                cmp byte [D.D._ovl_umb],0		; see if UMB specified
   515 000000ED 7405                        je  init_chkems			; no
   516 000000EF E82113                  	call	umb_check_setup	; see if UMB is available
   517 000000F2 7200                    	jc	init_chkems			; no
   518                                  
   519                                  ; check if EMS specified, if so, see if available, if so, use it for overlay pool
   520                                  init_chkems:
   521 000000F4 803E[7B09]00                cmp byte [D.D._ovl_ems_pool_flag],0  ; see if ems specified
   522 000000F9 7428                        je  init_xms            ; no
   523 000000FB E80314                      call    ems_check_setup
   524 000000FE E84F14                  	call	ovl_ems_poolcheck
   525 00000101 803E[7B09]00                cmp byte [D.D._ovl_ems_pool_flag],0  ; see if ems available
   526 00000106 741B                        je  init_xms            ; no
   527                                  
   528 00000108 B87E00                      mov ax,126
   529 0000010B A3[0801]                    mov [D.D._ovl_amt_512],ax   ; save 512 blocks allocated
   530 0000010E B8C00F                      mov ax,0fc0h            ; 4032 paragraphs (63K)
   531 00000111 A3[0601]                    mov [D.D._ovl_amt_alloc],ax ; save amount of memory allocated
   532 00000114 A1[8E09]                    mov ax,[D.D._ovl_ems_base]  ; get EMS base
   533                                  
   534 00000117 2EA3[0A00]                  mov [cs:D.D._ovl_load_start],ax ; save segment of overlay load area
   535 0000011B 0306[0601]                  add ax,[D.D._ovl_amt_alloc] ; calculate paragraph just above overlay load area
   536 0000011F 2EA3[0C00]                  mov [cs:D.D._ovl_load_end],ax   ; save to memory variable
   537                                  
   538                                  init_xms:
   539 00000123 803E[7C09]00                cmp byte [D.D._ovl_ort],0        ; see if XMS active overlay swapout specified
   540 00000128 740A                        je  init_lim40          ; no
   541 0000012A E8F114                      call    get_xms_for_ort ; try and grab some XMS for /ort swapping
   542 0000012D 803E[7C09]00                cmp byte [D.D._ovl_ort],0        ; see if XMS available
   543 00000132 750A                        jne init_1b             ; yes
   544                                  
   545                                  init_lim40:
   546 00000134 803E[7D09]00                cmp byte [D.D._ovl_orp],0        ; see if LIM 4.0 EMS active overlay swapout specified
   547 00000139 7403                        je  init_1b             ; no
   548 0000013B E88F15                      call    get_ems_for_orp ; try and grab some EMS for /orp swapping
   549                                  
   550                                  init_1b:
   551 0000013E 803E[7B09]00                cmp byte [D.D._ovl_ems_pool_flag],0  ; see if ems page frame used for overlay pool
   552 00000143 7408                        je  init_notox          ; no
   553                                  
   554                                  init_zeropool:
   555 00000145 31C9                        xor cx,cx               ; zero overlay pool size to allocate
   556 00000147 A1[0801]                	mov	ax,[D.D._ovl_amt_512]	; 512 byte chunks allocated in ax
   557 0000014A E98100                      jmp NEAR PTR init_compalloc
   558                                  
   559                                  ; ax == free memory prior to overlay pool allocation after all other allocations
   560                                  init_notox:
   561 0000014D 8B0E[F400]                  mov cx,WORD PTR [D.D._ovl_pool] ; get low word of pool size
   562 00000151 8B1E[F600]                  mov bx,WORD PTR [D.D._ovl_pool+2]   ; get high word of pool size
   563 00000155 D1EB                        shr bx,1
   564 00000157 D1D9                        rcr cx,1                ; convert to paragraphs in cx
   565 00000159 D1EB                        shr bx,1
   566 0000015B D1D9                        rcr cx,1
   567 0000015D D1EB                        shr bx,1
   568 0000015F D1D9                        rcr cx,1
   569 00000161 D1EB                        shr bx,1
   570 00000163 D1D9                        rcr cx,1                ; cx holds overlay pool size in paragraphs
   571                                  
   572 00000165 803E[0201]00                cmp byte [D.D._ovl_mem_alloc_flag],0 ; see which way to allocate memory
   573 0000016A 752E                        jne init_use_pool           ; allocate ovl_pool for overlay pool
   574                                  
   575                                  ; when using UMB overlay pool allocation for "minus" overlay pool (leave free)
   576                                  ; choose an UMB size of 3*largest overlay
   577 0000016C 803E[8209]00            	cmp	byte [D.D._ovl_umb],0		; check if using UMB for overlay pool
   578 00000171 7417                    	je	init_freealloc		; no
   579 00000173 8B1E[0001]              	mov	bx,[D.D._ovl_min_alloc]
   580 00000177 01DB                    	add	bx,bx
   581 00000179 031E[0001]              	add	bx,[D.D._ovl_min_alloc]	; bx == 3*largest overlay
   582 0000017D 391E[A10B]              	cmp	[umb_avail],bx		; see if enough UMB space for 3x pool
   583 00000181 7207                    	jb	init_freealloc		; no
   584 00000183 89D9                    	mov	cx,bx				; get allocation size in cx for umb_pool_alloc proc
   585 00000185 E8FD12                  	call	umb_pool_alloc	; allocate UMB for overlay pool
   586 00000188 EBBB                    	jmp	SHORT init_zeropool
   587                                  
   588                                  ; allocate all memory except amount in ovl_pool
   589                                  init_freealloc:
   590 0000018A C606[8209]00            	mov	byte [D.D._ovl_umb],0		; fail using UMB for overlay pool
   591 0000018F 39C8                        cmp ax,cx               ; see if enough memory for to leave ovl_pool amount free
   592 00000191 7303                        jae init_1c
   593                                  
   594                                  to_init_memerr2:
   595 00000193 E924FF                      jmp NEAR PTR init_memerr    ; no, out of memory
   596                                  
   597                                  init_1c:
   598 00000196 29C8                        sub ax,cx               ; ax holds amount of paragraphs for overlay load area
   599 00000198 EB1D                        jmp SHORT init_allocate ; bypass ovl_pool memory calculation
   600                                  
   601                                  ; allocate up to amount of memory in ovl_pool
   602                                  init_use_pool:
   603 0000019A 803E[8209]00            	cmp	byte [D.D._ovl_umb],0		; check if using UMB for overlay pool
   604 0000019F 740B                    	je	init_noumb			; no
   605 000001A1 390E[A10B]              	cmp	[umb_avail],cx		; see if enough UMB space for overlay pool
   606 000001A5 7205                    	jb	init_noumb			; no
   607 000001A7 E8DB12                  	call	umb_pool_alloc	; allocate UMB for overlay pool, using size in cx
   608 000001AA EB99                    	jmp	SHORT init_zeropool
   609                                  
   610                                  init_noumb:
   611 000001AC C606[8209]00            	mov	byte [D.D._ovl_umb],0		; fail using UMB for overlay pool
   612 000001B1 39C8                        cmp ax,cx               ; see if free memory is less than or equal to overlay pool size
   613 000001B3 7602                        jbe init_allocate       ; yes, allocate all of it
   614 000001B5 89C8                        mov ax,cx               ; only allocate amount of memory up to maximum
   615                                  
   616                                  ; ax holds, in paragraphs, the amount of memory to allocate for the memory pool
   617                                  ; si holds the amount of memory to allocate for the stack
   618                                  ; di holds the amount of memory to allocate for the loaded overlay array
   619                                  ; dx holds original memory allocation amount
   620                                  ; $$_ovl_filepos_size holds the amount of memory to allocate for file position table
   621                                  ; also remember to subtract off 10h paragraphs for memory block allocation overhead
   622                                  init_allocate:
   623 000001B7 3B06[0001]                  cmp ax,[D.D._ovl_min_alloc] ; see if enough memory for largest overlay
   624 000001BB 72D6                        jb  to_init_memerr2     ; no, force out of memory error
   625                                  
   626                                  init_alloc2:
   627 000001BD 89C1                        mov cx,ax               ; save memory pool paragraph allocation in cx
   628 000001BF 48                          dec ax                  ; make relative zero
   629 000001C0 D1E8                        shr ax,1                ; convert to 512 blocks, /2
   630 000001C2 D1E8                        shr ax,1
   631 000001C4 D1E8                        shr ax,1                ; /8
   632 000001C6 D1E8                        shr ax,1                ; /16
   633 000001C8 D1E8                        shr ax,1                ; /32
   634 000001CA 40                          inc ax                  ; adjust for beginning block
   635 000001CB A3[0801]                    mov [D.D._ovl_amt_512],ax   ; save 512 blocks allocated 
   636                                  
   637                                  init_compalloc:
   638 000001CE 29CA                        sub dx,cx				; subtract off memory pool
   639 000001D0 29F2                        sub dx,si				; stack allocation
   640 000001D2 29FA                        sub dx,di				; overlay loaded array
   641 000001D4 2B16[2601]                  sub dx,[D.D._ovl_filepos_size]	; file position table
   642 000001D8 01C0                    	add	ax,ax				; check array size is 512 bytes*2 (word per)
   643                                  
   644                                  ; 9/2/92
   645 000001DA A3[5801]                    mov [check_array_size],ax ; keep it
   646 000001DD 83C00F                  	add	ax,15				; round up to next para
   647 000001E0 D1E8                    	shr	ax,1
   648 000001E2 D1E8                    	shr	ax,1
   649 000001E4 D1E8                    	shr	ax,1
   650 000001E6 D1E8                    	shr	ax,1				; convert to paras
   651                                  
   652 000001E8 29C2                    	sub	dx,ax				; check array allocation
   653 000001EA 83EA10                      sub dx,10h              ; subtract off play, dx holds new allocation amount
   654 000001ED 89D3                        mov bx,dx               ; get allocation amount in bx
   655 000001EF B44A                        mov ah,4ah              ; modify memory allocation
   656 000001F1 CD21                        int 21h                 ; es already -> PSP for memory block to be modified
   657 000001F3 7308                        jnc init_get_free       ; no errors
   658                                  
   659                                  init_to_doserr:
   660 000001F5 E8A010                      call NEAR PTR D.D._ovl_dos_error  ; no return
   661                                  
   662                                  to_main_entry:
   663 000001F8 2EFF2E[2C00]                jmp far [cs:D.D._main_entry]  ; transfer control to program
   664                                  
   665                                  ; allocate from newly created free space for overlay setup
   666                                  init_get_free:
   667 000001FD 8CC0                        mov ax,es
   668 000001FF 01D0                        add ax,dx               ; ax holds new top of memory for program
   669 00000201 26A30200                    mov [es:2],ax           ; save back to PSP variable
   670                                  
   671 00000205 A0[7B09]                	mov	al,[D.D._ovl_ems_pool_flag]
   672 00000208 0A06[8209]              	or	al,[D.D._ovl_umb]		; see if EMS or UMB overlay pool used
   673 0000020C 7518                        jne init_2              ; yes, bypass allocation and setup
   674                                  
   675 0000020E 89CB                        mov bx,cx               ; bx holds paragraphs to allocate for overlay load area
   676                                  
   677 00000210 891E[0601]                  mov [D.D._ovl_amt_alloc],bx ; save amount of memory allocated
   678 00000214 B448                        mov ah,48h              ; allocate memory
   679 00000216 CD21                        int 21h
   680 00000218 72DB                        jc  init_to_doserr      ; error occurred
   681                                  
   682 0000021A 2EA3[0A00]                  mov [cs:D.D._ovl_load_start],ax ; save segment of overlay load area
   683 0000021E 0306[0601]                  add ax,[D.D._ovl_amt_alloc] ; calculate paragraph just above overlay load area
   684 00000222 2EA3[0C00]                  mov [cs:D.D._ovl_load_end],ax   ; save to memory variable
   685                                  
   686                                  init_2:
   687 00000226 E83E01                      call    read_ovl_filepos    ; allocate space for and read table into memory
   688                                  
   689                                  ; compute count of 512*2 chunks of overlay pool
   690 00000229 8B1E[0801]              	mov	bx,[D.D._ovl_amt_512]	; count of 512 chunks
   691 0000022D 01DB                    	add	bx,bx				; *2
   692                                  
   693                                  ; 9/2/92
   694 0000022F 83C30F                  	add	bx,15				; round up to next para
   695 00000232 D1EB                    	shr	bx,1
   696 00000234 D1EB                    	shr	bx,1
   697 00000236 D1EB                    	shr	bx,1
   698 00000238 D1EB                    	shr	bx,1				; convert to paras
   699                                  
   700 0000023A B448                        mov ah,48h              ; allocate memory
   701 0000023C CD21                        int 21h
   702 0000023E 72B5                        jc  init_to_doserr      ; error occurred
   703 00000240 A3[F70B]                    mov [check_array],ax      ; save check array address
   704                                  
   705 00000243 89F3                        mov bx,si               ; bx holds paragraphs to allocate for stack
   706 00000245 B448                        mov ah,48h              ; allocate memory
   707 00000247 CD21                        int 21h
   708 00000249 72AA                        jc  init_to_doserr      ; error occurred
   709                                  
   710 0000024B 2EA3[0600]                  mov [cs:D.D._ovl_stack_start],ax    ; save segment of stack
   711 0000024F A1[FE00]                    mov ax,[D.D._ovl_stack]     ; get stack size in bytes
   712 00000252 2EA3[0400]                  mov [cs:D.D._ovl_stack_ptr],ax  ; init stack pointer to top of stack
   713                                  
   714 00000256 89FB                        mov bx,di               ; bx holds paragraphs to allocate for overlay loaded array
   715 00000258 B448                        mov ah,48h              ; allocate memory
   716 0000025A CD21                        int 21h
   717 0000025C 7297                        jc  init_to_doserr      ; error occurred
   718                                  
   719 0000025E A3[0401]                    mov [D.D._ovl_array_start],ax   ; save segment of overlay loaded array
   720 00000261 89F9                        mov cx,di               ; cx holds number of array elements
   721 00000263 1E                      	push	ds				; save -> overlay manager data
   722 00000264 8ED8                        mov ds,ax               ; ds -> overlay array start
   723 00000266 31C0                        xor ax,ax
   724 00000268 89C3                        mov bx,ax               ; bx offsets into array area
   725                                  
   726                                  array_zloop:
   727 0000026A 8907                        mov [bx],ax             ; zero the array element identifiers
   728 0000026C 894704                      mov [bx+4],ax           ; zero activity level
   729 0000026F 83C310                      add bx,16               ; move to next element
   730 00000272 E2F6                        loop    array_zloop     ; loop until all ids are zeroed
   731                                  
   732                                  ; save old termination address in PSP, set to new
   733 00000274 26A10A00                    mov ax,[es:10]
   734 00000278 2EA3[3E00]                  mov WORD PTR [cs:psp_terminate],ax
   735 0000027C 26A10C00                    mov ax,[es:12]
   736 00000280 2EA3[4000]                  mov WORD PTR [cs:psp_terminate+2],ax
   737 00000284 B8[AC13]                    mov ax,OFFSET new_terminate
   738 00000287 26A30A00                    mov [es:10],ax
   739 0000028B B8[ssss]                    mov ax,SEG new_terminate
   740 0000028E 26A30C00                    mov [es:12],ax
   741                                  
   742                                  ; allocate space for /oht or /ohp overlay file swapouts if requested
   743 00000292 1F                          pop ds					; restore ds -> overlay manager data
   744 00000293 803E[7F09]00            	cmp	byte [D.D._ovl_oht],0		; see if /oht switch set
   745 00000298 740A                    	je	init_chkohp			; no
   746 0000029A E8AA13                      call    get_xms_for_oht ; attempt XMS allocation for /oht swapping
   747 0000029D 803E[7F09]00                cmp byte [D.D._ovl_oht],0        ; see if XMS was allocated
   748 000002A2 750A                        jne init_out            ; yes
   749                                  
   750                                  init_chkohp:
   751 000002A4 803E[7E09]00            	cmp	byte [D.D._ovl_ohp],0		; see if /ohp switch set
   752 000002A9 7403                    	je	init_out			; no
   753 000002AB E84714                      call    get_ems_for_ohp ; attempt EMS allocation for /ohp swapping
   754                                  
   755                                  init_out:
   756 000002AE 1F                          pop ds                  ; restore data segment entry value
   757 000002AF 2EA1[0200]                  mov ax,[cs:prog_ss_store]
   758 000002B3 2E8B1E[0000]                mov bx,[cs:prog_sp_store] ; get stack entry values
   759 000002B8 FA                          cli                     ; shut off interrupts while stack is set
   760 000002B9 8ED0                        mov ss,ax
   761 000002BB 89DC                        mov sp,bx               ; set internal stack
   762 000002BD FB                          sti                     ; turn interrupts back on
   763 000002BE E937FF                  	jmp	NEAR PTR to_main_entry
   764                                  D.D._ovl_init ENDP
   765                                  
   766                                  ;*****************************
   767                                  ;* GET_OVL_TOTAL             *
   768                                  ;*****************************
   769                                  
   770                                  ; open overlay file, read total number of overlays from first word
   771                                  ; upon entry ax holds number of free paragraphs
   772                                  ; destroys bx,cx
   773                                  ; modifies ax
   774                                  
   775                                  get_ovl_total   PROC    NEAR
   776 000002C1 52                          push    dx              ; save critical register
   777 000002C2 50                          push    ax
   778                                  
   779                                  err_retry2:
   780 000002C3 BA[4600]                    mov dx,OFFSET D.D._ovl_filename   ; ds:dx -> file spec
   781 000002C6 B8403D                      mov ax,3d40h            ; open, read access
   782 000002C9 CD21                        int 21h 
   783 000002CB 7305                        jnc ovl_file_open       ; no errors
   784                                  
   785 000002CD E8C80F                      call NEAR PTR D.D._ovl_dos_error
   786 000002D0 EBF1                        jmp SHORT err_retry2
   787                                  
   788                                  ovl_file_open:
   789 000002D2 A3[2401]                    mov [D.D._ovl_file_handle],ax   ; save overlay file handle
   790 000002D5 2E803E[3A00]00              cmp byte [cs:D.D._ovl_internal_flag],0   ; see if internal overlays
   791 000002DB 744B                        je  got_1               ; no
   792                                  
   793                                  err_retry3:
   794 000002DD 8B1E[2401]                  mov bx,[D.D._ovl_file_handle]
   795 000002E1 B90600                      mov cx,6                ; read first 6 bytes of EXE file
   796 000002E4 BA[2A01]                    mov dx,OFFSET D.D._ovl_temp_buff  ; into the temporary buffer
   797 000002E7 B43F                        mov ah,3fh              ; read file
   798 000002E9 CD21                        int 21h
   799 000002EB 7305                        jnc got_read1           ; no error
   800                                  
   801 000002ED E8A80F                      call NEAR PTR D.D._ovl_dos_error
   802 000002F0 EBEB                        jmp SHORT err_retry3
   803                                  
   804                                  got_read1:
   805 000002F2 8B0E[2E01]                  mov cx,WORD PTR [D.D._ovl_temp_buff+4]  ; get size of file in 512-byte pages
   806 000002F6 A1[2C01]                    mov ax,WORD PTR [D.D._ovl_temp_buff+2]  ; get size of file modulo 512
   807 000002F9 09C0                        or  ax,ax               ; see if any remainder
   808 000002FB 7401                        je  get_int_1           ; no
   809 000002FD 49                          dec cx                  ; drop count of pages
   810                                  
   811                                  get_int_1:
   812 000002FE 88CE                        mov dh,cl
   813 00000300 88E9                        mov cl,ch
   814 00000302 30D2                        xor dl,dl
   815 00000304 88D5                        mov ch,dl               ; effectively multiply page value by 256 in cx:dx
   816 00000306 D1E2                        shl dx,1
   817 00000308 D1D1                        rcl cx,1                ; get page value*512 in cx:dx
   818 0000030A 01C2                        add dx,ax               ; add in page remainder
   819 0000030C 83D100                      adc cx,0                ; carry to high word
   820 0000030F 8916[2A01]                  mov WORD PTR [D.D._ovl_temp_buff],dx    ; save low word of file end offset
   821 00000313 890E[2C01]                  mov WORD PTR [D.D._ovl_temp_buff+2],cx  ; save high word of file end offset
   822                                  
   823                                  err_retry9:
   824 00000317 8B1E[2401]                  mov bx,[D.D._ovl_file_handle]
   825 0000031B 8B0E[2C01]                  mov cx,WORD PTR [D.D._ovl_temp_buff+2]
   826 0000031F 8B16[2A01]                  mov dx,WORD PTR [D.D._ovl_temp_buff]
   827 00000323 B80042                      mov ax,4200h            ; move file pointer, absolute byte offset
   828 00000326 CD21                        int 21h
   829                                  
   830                                  got_1:
   831 00000328 B90200                      mov cx,2                ; read one word (total number of overlays)
   832 0000032B BA[2801]                    mov dx,OFFSET D.D._ovl_total_count    ; read bytes into memory variable
   833 0000032E 8B1E[2401]                  mov bx,[D.D._ovl_file_handle]
   834 00000332 B43F                        mov ah,3fh              ; read file
   835 00000334 CD21                        int 21h
   836 00000336 7305                        jnc got_read2           ; no error
   837                                  
   838 00000338 E85D0F                      call NEAR PTR D.D._ovl_dos_error
   839 0000033B EBDA                        jmp SHORT err_retry9
   840                                  
   841                                  got_read2:
   842 0000033D 8B0E[2801]                  mov cx,[D.D._ovl_total_count]   ; cx holds number of entries in table
   843 00000341 D1E1                        shl cx,1
   844 00000343 D1E1                        shl cx,1                ; cx holds total bytes (doubleword entries) of overlay file position table
   845 00000345 890E[2801]                  mov [D.D._ovl_total_count],cx   ; save total number of bytes
   846 00000349 83C10F                      add cx,15               ; round up to next paragraph
   847 0000034C D1E9                        shr cx,1                ; convert table size to paragraphs
   848 0000034E D1E9                        shr cx,1                ; /4
   849 00000350 D1E9                        shr cx,1                ; /8
   850 00000352 D1E9                        shr cx,1                ; /16, cx holds table size in paragraphs
   851 00000354 890E[2601]                  mov [D.D._ovl_filepos_size],cx  ; save size
   852 00000358 58                          pop ax                  ; ax holds free paragraphs
   853                                  
   854 00000359 39C8                        cmp ax,cx               ; make sure excess memory is equal to or greater than table allocation
   855 0000035B 7306                        jae got_2               ; yes
   856                                  
   857 0000035D B80800                      mov ax,8                ; no, force out of memory error
   858 00000360 E8350F                      call NEAR PTR D.D._ovl_dos_error  ; no return
   859                                  
   860                                  got_2:
   861 00000363 29C8                        sub ax,cx               ; subtract off file position table allocation
   862 00000365 5A                          pop dx                  ; restore critical register
   863 00000366 C3                          ret
   864                                  get_ovl_total   ENDP
   865                                  
   866                                  ;*****************************
   867                                  ;* READ_OVL_FILEPOS          *
   868                                  ;*****************************
   869                                  
   870                                  ; allocate memory for overlay file positions table, then read table into memory
   871                                  ; if internal overlays adjust table entries past EXE file
   872                                  ; destroys ax,bx,cx,dx
   873                                  
   874                                  read_ovl_filepos    PROC    NEAR
   875 00000367 8B1E[2601]                  mov bx,[D.D._ovl_filepos_size]  ; bx holds paragraphs to allocate for overlay file position table
   876 0000036B B448                        mov ah,48h              ; allocate memory
   877 0000036D CD21                        int 21h
   878 0000036F 7303                        jnc rof_2               ; no error
   879 00000371 E8240F                      call NEAR PTR D.D._ovl_dos_error  ; no return
   880                                  
   881                                  rof_2:
   882 00000374 A3[0A01]                    mov [D.D._ovl_filepos],ax   ; save segment of overlay load area
   883                                  
   884                                  err_retry4:
   885 00000377 8B0E[2801]                  mov cx,[D.D._ovl_total_count]   ; read number of bytes in table
   886 0000037B 8B1E[2401]                  mov bx,[D.D._ovl_file_handle]
   887 0000037F 31D2                        xor dx,dx
   888 00000381 1E                          push    ds
   889 00000382 8E1E[0A01]                  mov ds,[D.D._ovl_filepos]   ; ds:dx -> load area for overlay file position table
   890 00000386 B43F                        mov ah,3fh              ; read file
   891 00000388 CD21                        int 21h
   892 0000038A 1F                          pop ds                  ; restore ds
   893 0000038B 7305                        jnc rof_open            ; no error
   894                                  
   895 0000038D E8080F                      call NEAR PTR D.D._ovl_dos_error  ; no return 
   896 00000390 EBE5                        jmp SHORT err_retry4
   897                                  
   898                                  rof_open:
   899 00000392 2E803E[3A00]00              cmp byte [cs:D.D._ovl_internal_flag],0   ; see if internal overlays
   900 00000398 7423                        je  rof_ret             ; no
   901                                  
   902                                  ; make adjustments to overlay file position table for internal overlay
   903 0000039A 8B0E[2801]                  mov cx,[D.D._ovl_total_count]   ; get total number of bytes in table
   904 0000039E D1E9                        shr cx,1
   905 000003A0 D1E9                        shr cx,1                ; convert back to number of overlays
   906 000003A2 A1[2A01]                    mov ax,WORD PTR [D.D._ovl_temp_buff]    ; get low word of adjustment
   907 000003A5 8B16[2C01]                  mov dx,WORD PTR [D.D._ovl_temp_buff+2]  ; get high word of adjustment
   908 000003A9 8B1E[0A01]                  mov bx,[D.D._ovl_filepos]   ; get segment of overlay load area
   909 000003AD 1E                          push    ds              ; save ds-> overlay manager data
   910 000003AE 8EDB                        mov ds,bx
   911 000003B0 31DB                        xor bx,bx               ; ds:bx -> overlay file position table
   912                                  
   913                                  adjust_loop:
   914 000003B2 0107                        add [bx],ax             ; add in low word of adjustment
   915 000003B4 115702                      adc [bx+2],dx           ; ad in high word of adjustment plus carry
   916 000003B7 83C304                      add bx,4                ; move to next entry in overlay file position table
   917 000003BA E2F6                        loop    adjust_loop     ; loop until all adjustments done
   918                                  
   919 000003BC 1F                          pop ds                  ; restore ds -> overlay manager data
   920                                  
   921                                  rof_ret:
   922 000003BD C3                          ret
   923                                  read_ovl_filepos    ENDP
   924                                  
   925                                  ;*****************************
   926                                  ;* $$_OVL_FIND_OVL_FILE      *
   927                                  ;*****************************
   928                                  
   929                                  ; find .OVL file using PATH environment string
   930                                  ; prior to using PATH, if using DOS 3.x+, check the EXE's path that is found
   931                                  ; after the local environment block (argv[0])
   932                                  ; es -> PSP upon entry
   933                                  ; dx -> file name upon entry
   934                                  ; destroys ax,bx,cx,dx,si,di
   935                                  
   936                                  D.D._ovl_find_ovl_file    PROC    NEAR
   937 000003BE 06                          push    es              ; save critical register
   938                                  
   939                                  ; get overlay file name in $$_ovl_tfile from $$_ovl_filename, so can append path to it
   940 000003BF BF[0C01]                    mov di,OFFSET D.D._ovl_tfile
   941 000003C2 BE[4600]                    mov si,OFFSET D.D._ovl_filename
   942 000003C5 1E                          push    ds
   943 000003C6 07                          pop es                  ; es -> overlay manager data
   944                                  
   945                                  ovl_findloop:
   946 000003C7 A4                          movsb                   ; move a filename char
   947 000003C8 807CFF00                    cmp BYTE PTR [si-1],0   ; see if all chars transferred
   948 000003CC 75F9                        jne ovl_findloop        ; no
   949                                  
   950 000003CE 07                          pop es                  ; restore es -> PSP
   951 000003CF 06                          push    es              ; put PSP value back on stack
   952 000003D0 26A12C00                    mov ax,[es:2ch]         ; get environment segment from offset 2ch in PSP
   953 000003D4 85C0                    	test ax, ax		; environment valid ?
   954 000003D6 7477                    	jz ovl_not_found	; no -->
   955 000003D8 8EC0                        mov es,ax               ; es -> environment segment
   956                                  
   957 000003DA B430                        mov ah,30h              ; get MS-DOS version number
   958 000003DC CD21                        int 21h
   959 000003DE 3C02                        cmp al,2                ; should be 3.x or above
   960 000003E0 7659                        jbe dos_2x_entry        ; no, can't check path of EXE file after environment blockk
   961                                  
   962                                  ; search for end of environment block
   963 000003E2 8CDB                        mov bx,ds
   964 000003E4 06                      	push	es
   965 000003E5 1F                      	pop	ds
   966 000003E6 8EC3                        mov es,bx               ; es -> warplink data
   967 000003E8 31F6                        xor si,si               ; ds:si -> start of environment
   968                                  
   969                                  end_loop:
   970 000003EA AC                          lodsb                   ; get environment char
   971 000003EB 0A04                        or  al,[si]             ; merge in next char
   972 000003ED 75FB                        jne end_loop            ; not at end of environment block
   973                                  
   974 000003EF 83C603                      add si,3                ; bump si -> start of exe file path
   975 000003F2 89F7                        mov di,si               ; save start pointer
   976                                  
   977                                  path_loop:
   978 000003F4 AC                          lodsb                   ; get char of file path
   979 000003F5 08C0                        or  al,al               ; see if at end
   980 000003F7 7408                        je  calc_path           ; yes
   981 000003F9 3C5C                        cmp al,'\'              ; see if directory indicator
   982 000003FB 75F7                        jne path_loop           ; no
   983 000003FD 89F3                        mov bx,si               ; save -> to char past directory
   984 000003FF EBF3                        jmp SHORT path_loop     ; get next char
   985                                  
   986                                  calc_path:
   987 00000401 89FE                        mov si,di               ; ds:si -> start  of file path
   988 00000403 89D7                        mov di,dx               ; es:di -> program name with path prefix slot
   989                                  
   990                                  calc_loop:
   991 00000405 A4                          movsb                   ; transfer a char
   992 00000406 39DE                        cmp si,bx               ; see if at end of path
   993 00000408 75FB                        jne calc_loop           ; no
   994                                  
   995 0000040A 8CDB                        mov bx,ds               ; save -> environment block
   996 0000040C 06                      	push	es
   997 0000040D 1F                      	pop	ds					; ds -> machlink data
   998 0000040E BE[0C01]                    mov si,OFFSET D.D._ovl_tfile  ; append program name to end of path prefix
   999                                  
  1000                                  append_loop:
  1001 00000411 A4                          movsb                   ; transfer a char
  1002 00000412 807CFF00                    cmp BYTE PTR [si-1],0   ; see if null terminator transferred
  1003 00000416 75F9                        jne append_loop         ; no
  1004                                  
  1005                                  ; $$_ovl_filename holds EXE file path and OVL file name
  1006                                  err_retry5:
  1007 00000418 B80043                      mov ax,4300h            ; get file attributes (check for file existence)
  1008 0000041B CD21                        int 21h
  1009 0000041D 7203                        jc  check_errors        ; program not found, make sure non-DOS error
  1010 0000041F E9A300                      jmp NEAR PTR find_ovl_ret   ; program found, return with $$_ovl_filename properly set up
  1011                                  
  1012                                  check_errors:
  1013 00000422 83F802                      cmp ax,2                ; file not found
  1014 00000425 7412                        je  try_path
  1015 00000427 83F803                      cmp ax,3                ; path not found
  1016 0000042A 740D                        je  try_path
  1017 0000042C 83F805                      cmp ax,5                ; access denied error
  1018 0000042F 7408                        je  try_path
  1019                                  
  1020                                  find_retry:
  1021 00000431 E8640E                      call    NEAR PTR D.D._ovl_dos_error
  1022 00000434 BA[4600]                    mov dx,OFFSET D.D._ovl_filename   ; ds:dx -> filename for retry
  1023 00000437 EBDF                        jmp SHORT err_retry5
  1024                                  
  1025                                  ; file wasn't found in EXE's path, try PATH environment variable
  1026                                  try_path:
  1027 00000439 8EC3                        mov es,bx               ; es -> environment block
  1028                                  
  1029                                  dos_2x_entry:
  1030 0000043B BB[4100]                    mov bx,OFFSET pathtext  ; bx holds target string address for compares
  1031 0000043E 31F6                        xor si,si               ; starting location for target string check
  1032                                  
  1033                                  ovl_find_path:
  1034 00000440 31FF                        xor di,di               ; offset into target string
  1035                                  
  1036                                  ovl_loop2:
  1037 00000442 268A04                      mov al,[es:si]          ; get byte from environment string
  1038 00000445 46                          inc si                  ; point to next char in environment
  1039 00000446 3A01                        cmp al,[bx+di]          ; does environment char match PATH string char
  1040 00000448 740A                        je  ovl_byte_match      ; yes, try next location
  1041 0000044A 260A04                      or  al,[es:si]          ; two zero values in a row mean the end of the environment
  1042 0000044D 75F1                        jne ovl_find_path       ; not the end of the environment
  1043                                  
  1044                                  ovl_not_found:
  1045 0000044F B80200                      mov ax,2                ; force file not found error
  1046 00000452 EBDD                        jmp SHORT find_retry    ; transfer to error handler
  1047                                  
  1048                                  ; check that PATH is not part of another environment string
  1049                                  ovl_byte_match:
  1050 00000454 09FF                        or  di,di               ; di is zero if first char is matched
  1051 00000456 750C                        jne ovl_2               ; not first char, test already done
  1052 00000458 83FE01                      cmp si,1                ; si equals one if PATH is first string in environment block
  1053 0000045B 7407                        je  ovl_2               ; no previous environment string
  1054 0000045D 26807CFE00                  cmp BYTE PTR [es:si-2],0    ; check if char before PATH was nonzero
  1055 00000462 75DC                        jne ovl_find_path       ; yes, LIB is a subset of another string, keep looking
  1056                                  
  1057                                  ovl_2:
  1058 00000464 47                          inc di                  ; a match, move to next byte of target string
  1059 00000465 83FF05                      cmp di,5                ; check if all bytes matched
  1060 00000468 72D8                        jb  ovl_loop2           ; not yet, keep comparing
  1061                                  
  1062                                  ovl_path_found:
  1063 0000046A 89D3                        mov bx,dx               ; bx-> program name with path prefix slot
  1064                                  
  1065                                  ovl_3:
  1066 0000046C 31FF                        xor di,di               ; offset into path prefix
  1067                                  
  1068                                  ovl_4:
  1069 0000046E 268A04                      mov al,[es:si]          ; get path character
  1070 00000471 3C3B                        cmp al,';'              ; check if path terminator character
  1071 00000473 740A                        je  ovl_prefix_complete ; yes, check file's existence with the current path prefix
  1072 00000475 3C20                        cmp al,' '              ; anything less than a space is also a terminator character
  1073 00000477 7206                        jb  ovl_prefix_complete
  1074 00000479 8801                        mov [bx+di],al          ; save path character
  1075 0000047B 47                          inc di                  ; move to next name slot
  1076 0000047C 46                          inc si                  ; move to next byte location
  1077 0000047D EBEF                        jmp SHORT ovl_4         ; loop for next character
  1078                                  
  1079                                  ovl_prefix_complete:
  1080 0000047F 56                          push    si              ; save si -> current environment position
  1081 00000480 BE[0C01]                    mov si,OFFSET D.D._ovl_tfile  ; append program name to end of path prefix
  1082 00000483 8079FF5C                    cmp BYTE PTR [bx+di-1],'\'  ; check for backslash already in place
  1083 00000487 7404                        je  ovl_5
  1084 00000489 C6015C                      mov BYTE PTR [bx+di],'\'    ;put a backslash between the path and program name
  1085 0000048C 47                          inc di                  ; point di past backslash
  1086                                  
  1087                                  ovl_5:
  1088 0000048D 8A04                        mov al,[si]             ; get program name character
  1089 0000048F 8801                        mov [bx+di],al          ; transfer program name
  1090 00000491 08C0                        or  al,al               ; stop transfer after first zero byte transfer
  1091 00000493 7404                        je  ovl_search          ; now see if file exists in this path
  1092 00000495 46                          inc si                  ; move to next name character slot
  1093 00000496 47                          inc di
  1094 00000497 EBF4                        jmp SHORT ovl_5         ; loop for next character
  1095                                  
  1096                                  ovl_search:
  1097 00000499 B80043                      mov ax,4300h            ; get file attributes (check for file existence)
  1098 0000049C CD21                        int 21h
  1099 0000049E 7324                        jnc ovl_prog_found      ; found the program
  1100 000004A0 83F802                      cmp ax,2                ; file not found
  1101 000004A3 740C                        je  ovl_6
  1102 000004A5 83F803                      cmp ax,3                ; path not found
  1103 000004A8 7407                        je  ovl_6
  1104 000004AA 83F805                      cmp ax,5                ; access denied
  1105 000004AD 7402                        je  ovl_6
  1106 000004AF EB80                        jmp SHORT find_retry    ; transfer to error handler
  1107                                  
  1108                                  ovl_6:
  1109 000004B1 5E                          pop si                  ; restore si -> environment block position
  1110 000004B2 26803C00                    cmp BYTE PTR [es:si],0  ; check last terminator
  1111 000004B6 7497                        je  ovl_not_found       ; if zero then no more path prefixes to try
  1112 000004B8 26807C0100                  cmp BYTE PTR [es:si+1],0    ; check character following last terminator
  1113 000004BD 7490                        je  ovl_not_found       ; if zero then no more path prefixes to try
  1114 000004BF EB00                        jmp SHORT ovl_search_again  ; not the final PATH path, keep trying
  1115                                  
  1116                                  ovl_search_again:
  1117 000004C1 46                          inc si                  ; point to first character after last terminator
  1118 000004C2 EBA8                        jmp SHORT ovl_3         ; try next path
  1119                                  
  1120                                  ovl_prog_found:
  1121 000004C4 5F                          pop di                  ; trash the value stored in the stack
  1122                                  
  1123                                  find_ovl_ret:
  1124 000004C5 07                          pop es                  ; restore critical register
  1125 000004C6 C3                          ret
  1126                                  D.D._ovl_find_ovl_file    ENDP
  1127                                  
  1128                                  ;*****************************
  1129                                  ;* $$_OVL_SEG_CALL_ENTRY     *
  1130                                  ;*****************************
  1131                                  
  1132                                  ; Call to overlaid segment, through target segment fixup
  1133                                  ; must assume that displacement is zero, valid assumption for Clipper
  1134                                  ; otherwise, don't allow multiple code segments in an overlay module
  1135                                  ; to avoid the possiblility of nonzero target displacments for overlaid segments
  1136                                  ; Check if segment shows this is call from root or overlay
  1137                                  ; if overlay walk the overlay loaded array checking the calling routine's
  1138                                  ; segment against loaded overlays' segments to find the proper source id for bx
  1139                                  
  1140                                  D.D._ovl_seg_call_entry PROC	FAR
  1141 000004C7 2EC606[3C00]01              mov byte [cs:D.D._ovl_in_manager], 1  ; flag used by profiler
  1142 000004CD 2EA3[1600]                  mov [cs:ax_store],ax      ; save ax,bx,cx,dx value
  1143 000004D1 2E891E[1800]                mov [cs:bx_store],bx
  1144 000004D6 2E890E[1A00]                mov [cs:cx_store],cx
  1145 000004DB 2E8916[1C00]                mov [cs:dx_store],dx
  1146 000004E0 9C                          pushf                   ; save the flag register
  1147 000004E1 2E8F06[2200]                pop word [cs:flag_store]
  1148 000004E6 58                          pop ax                  ; get offset from near call to vector jump
  1149 000004E7 83E813                      sub ax,13h              ; adjust for jump vector code at beginning of segment and for call offset
  1150 000004EA 31D2                        xor dx,dx               ; zero high word of dividend
  1151 000004EC BB0300                      mov bx,3
  1152 000004EF F7F3                        div bx                  ; call every three bytes, this gets overlay id number in ax
  1153                                  
  1154                                  ; ax now holds the overlaid identifier after division, relative zero
  1155 000004F1 40                          inc ax                  ; make overlay id number relative 1
  1156 000004F2 80CC80                      or  ah,80h              ; set flag for far call
  1157                                  
  1158 000004F5 59                          pop cx                  ; get indirect calling routine offset in cx
  1159 000004F6 5A                          pop dx                  ; get indirect calling routine segment in dx
  1160                                  
  1161 000004F7 2E890E[1200]                mov [cs:call_offset],cx   ; save calling routine offset
  1162                                  
  1163 000004FC BB00C0                      mov bx,0c000h           ; preset bx to show call from root via segment fixup
  1164 000004FF 2E3B16[0A00]                cmp dx,[cs:D.D._ovl_load_start] ; see if segment below overlay load area
  1165 00000504 7247                        jb  ovl_seg_to_main     ; yes, this is an indirect call from the root
  1166 00000506 2E3B16[0C00]                cmp dx,[cs:D.D._ovl_load_end]   ; see if segment above overlay load area
  1167 0000050B 7340                        jae ovl_seg_to_main     ; yes, indirect call from root
  1168                                  
  1169                                  ; call from overlay to overlay via segment fixup
  1170 0000050D 2E8C1E[2000]                mov [cs:ds_store],ds      ; save data segment, used for walking load overlay areas
  1171 00000512 2E833E[4400]00              cmp word [cs:last_access_slot],0   ; see if last accessed overlay
  1172 00000518 740B                        je  not_last            ; no
  1173 0000051A 2E8E1E[4400]                mov ds,[cs:last_access_slot]  ; ds -> last access overlay slot
  1174 0000051F 3B160600                    cmp dx,[6]           ; see if calling segment matches current segment
  1175 00000523 741C                        je  ovl_seg_found       ; yes, segment found
  1176                                  
  1177                                  not_last:
  1178 00000525 BB[ssss]                    mov bx,D.D._ovl_data
  1179 00000528 8EDB                        mov ds,bx               ; ds -> overlay manager data
  1180 0000052A 8B1E[0401]                  mov bx,[D.D._ovl_array_start]   ; bx -> overlay loaded array element
  1181 0000052E 31C9                        xor cx,cx
  1182                                  
  1183                                  ; bx -> overlay loaded array element
  1184                                  ; ax holds overlay identification number with flags
  1185                                  ; cx == 0
  1186                                  ; dx holds calling segment of routine
  1187                                  ovl_segjmp_loop:
  1188 00000530 8EDB                        mov ds,bx               ; ds -> overlay loaded array element
  1189 00000532 3B0E0000                    cmp cx,[0]           ; see if this array element was used
  1190 00000536 7406                        je  ovl_segjmp_next     ; no, try next one
  1191 00000538 3B160600                    cmp dx,[6]           ; see if calling segment matches current segment
  1192 0000053C 7403                        je  ovl_seg_found       ; yes, segment found
  1193                                  
  1194                                  ovl_segjmp_next:
  1195 0000053E 43                          inc bx                  ; bump to next overlay loaded array element
  1196 0000053F EBEF                        jmp SHORT ovl_segjmp_loop   ; see if matches
  1197                                  
  1198                                  ovl_seg_found:
  1199 00000541 8B1E0000                    mov bx,[0]           ; get overlay identifier in bx
  1200 00000545 80CF40                      or  bh,40h              ; set segment fixup reference bit
  1201 00000548 2E8E1E[2000]                mov ds,[cs:ds_store]      ; restore data segment
  1202                                  
  1203                                  ovl_seg_to_main:
  1204 0000054D 2E8916[1400]                mov [cs:call_segment],dx  ; save segment of calling routine
  1205 00000552 2E891E[0E00]                mov [cs:source_id],bx     ; save id of calling routine
  1206 00000557 2EA3[1000]                  mov [cs:destination_id],ax    ; save id of routine to call
  1207                                  
  1208 0000055B 2E8B16[1C00]                mov dx,[cs:dx_store]      ; restore dx to original value
  1209 00000560 2EFF36[2200]                push    word [cs:flag_store]   ; restore original flag values
  1210 00000565 9D                          popf
  1211 00000566 E9EA00                      jmp NEAR PTR vector_altent ; everything properly set up, transfer to main overlay driver
  1212                                  D.D._ovl_seg_call_entry ENDP
  1213                                  
  1214                                  ;*****************************
  1215                                  ;* $$_OVL_IND_2OVL_ENT       *
  1216                                  ;*****************************
  1217                                  
  1218                                  ; indirect call vector (from root or overlay) to overlay
  1219                                  ; the stack holds the offset of the near call to jump to the vector here,
  1220                                  ; used to compute which overlaid public is being called,
  1221                                  ; the segment:offset of the calling routine is also on the stack
  1222                                  ; indirect calls are always assumed to be FAR
  1223                                  ; check if segment shows this is call from root or overlay
  1224                                  ; if overlay walk the overlay loaded array checking the calling routine's
  1225                                  ; segment against loaded overlays' segments to find the proper source id for bx
  1226                                  
  1227                                  D.D._ovl_ind_2ovl_ent PROC    FAR
  1228 00000569 2EC606[3C00]01              mov byte [cs:D.D._ovl_in_manager], 1  ; flag used by profiler
  1229 0000056F 2EA3[1600]                  mov [cs:ax_store],ax      ; save ax,bx,cx,dx value
  1230 00000573 2E891E[1800]                mov [cs:bx_store],bx
  1231 00000578 2E890E[1A00]                mov [cs:cx_store],cx
  1232 0000057D 2E8916[1C00]                mov [cs:dx_store],dx
  1233 00000582 9C                          pushf                   ; save the flag register
  1234 00000583 2E8F06[2200]                pop word [cs:flag_store]
  1235 00000588 58                          pop ax                  ; get offset from near call to vector jump
  1236 00000589 83E813                      sub ax,13h              ; adjust for jump vector code at beginning of segment and for call offset
  1237 0000058C 31D2                        xor dx,dx               ; zero high word of dividend
  1238 0000058E BB0300                      mov bx,3
  1239 00000591 F7F3                        div bx                  ; call every three bytes, this gets public overlay number in ax
  1240                                  
  1241                                  ; ax now holds the overlaid public number after division, relative zero
  1242 00000593 40                          inc ax                  ; make public number relative 1
  1243 00000594 80CC80                      or  ah,80h              ; set flag for far call
  1244                                  
  1245 00000597 59                          pop cx                  ; get indirect calling routine offset in cx
  1246 00000598 5A                          pop dx                  ; get indirect calling routine segment in dx
  1247                                  
  1248                                  ind_altent:
  1249 00000599 2E890E[1200]                mov [cs:call_offset],cx   ; save calling routine offset
  1250                                  
  1251 0000059E BB0080                      mov bx,8000h            ; set bx to show call from root
  1252 000005A1 2E3B16[0A00]                cmp dx,[cs:D.D._ovl_load_start] ; see if segment below overlay load area
  1253 000005A6 7244                        jb  ovl_ind_to_main     ; yes, this is an indirect call from the root
  1254 000005A8 2E3B16[0C00]                cmp dx,[cs:D.D._ovl_load_end]   ; see if segment above overlay load area
  1255 000005AD 733D                        jae ovl_ind_to_main     ; yes, indirect call from root
  1256                                  
  1257                                  ; indirect call from overlay to overlay
  1258 000005AF 2E8C1E[2000]                mov [cs:ds_store],ds      ; save data segment, used for walking load overlay areas
  1259 000005B4 2E833E[4400]00              cmp word [cs:last_access_slot],0   ; see if last accessed overlay
  1260 000005BA 740B                        je  not_last2           ; no
  1261 000005BC 2E8E1E[4400]                mov ds,[cs:last_access_slot]  ; ds -> last access overlay slot
  1262 000005C1 3B160600                    cmp dx,[6]           ; see if calling segment matches current segment
  1263 000005C5 741C                        je  ovl_ind_found       ; yes
  1264                                  
  1265                                  not_last2:
  1266 000005C7 BB[ssss]                    mov bx,D.D._ovl_data
  1267 000005CA 8EDB                        mov ds,bx               ; ds -> overlay manager data
  1268 000005CC 8B1E[0401]                  mov bx,[D.D._ovl_array_start]   ; bx -> overlay loaded array element
  1269 000005D0 31C9                        xor cx,cx
  1270                                  
  1271                                  ; bx -> overlay loaded array element
  1272                                  ; ax holds overlay public number with flags
  1273                                  ; cx == 0
  1274                                  ; dx holds calling segment of routine
  1275                                  ovl_ind_loop:
  1276 000005D2 8EDB                        mov ds,bx               ; ds -> overlay loaded array element
  1277 000005D4 3B0E0000                    cmp cx,[0]           ; see if this array element was used
  1278 000005D8 7406                        je  ovl_ind_next        ; no, try next one
  1279 000005DA 3B160600                    cmp dx,[6]           ; see if calling segment matches current segment
  1280 000005DE 7403                        je  ovl_ind_found       ; yes
  1281                                  
  1282                                  ovl_ind_next:
  1283 000005E0 43                          inc bx                  ; bump to next overlay loaded array element
  1284 000005E1 EBEF                        jmp SHORT ovl_ind_loop  ; see if matches
  1285                                  
  1286                                  ovl_ind_found:
  1287 000005E3 8B1E0000                    mov bx,[0]           ; get overlay identifier in bx
  1288 000005E7 2E8E1E[2000]                mov ds,[cs:ds_store]      ; restore data segment
  1289                                  
  1290                                  ovl_ind_to_main:
  1291 000005EC 2E8916[1400]                mov [cs:call_segment],dx  ; save segment of calling routine
  1292 000005F1 2E891E[0E00]                mov [cs:source_id],bx     ; save id of calling routine
  1293 000005F6 2EA3[1000]                  mov [cs:destination_id],ax    ; save id of routine to call
  1294                                  
  1295 000005FA 2E8B16[1C00]                mov dx,[cs:dx_store]      ; restore dx to original value
  1296 000005FF 2EFF36[2200]                push    word [cs:flag_store]   ; restore original flag values
  1297 00000604 9D                          popf
  1298 00000605 EB4C                        jmp SHORT vector_altent ; everything properly set up, transfer to main overlay driver
  1299                                  D.D._ovl_ind_2ovl_ent ENDP
  1300                                  
  1301                                  ;*****************************
  1302                                  ;* $$_OVL_MGR_ENTRY          *
  1303                                  ;*****************************
  1304                                  
  1305                                  ; the main overlay manager driver
  1306                                  ; this procedure is far jumped to, NOT called to
  1307                                  ; upon entry ax contains public-in-overlay number (1-16383),
  1308                                  ; or destination overlaid identifier number if via segment fixup (set bit 6 of bx)
  1309                                  ; high bit (80h) of ah set if a far call to overlaid public
  1310                                  ; high bit (80h) of ah reset if near call
  1311                                  ; bit 6 (40h) of ah set if routine being called is not an overlay (root called from an overlay)
  1312                                  ; bx contains source identifier (1-16383)
  1313                                  ; high bit (80h) of bh set if calling routine is not an overlay (root calling an overlay)
  1314                                  ; bit 6 (40h) of bh set if calling routine is via segment fixup (assume zero offset)
  1315                                  ; cx contains segment of calling routine (needed for root calling overlay via NEAR call)
  1316                                  ; near/far address+ax+bx+cx are on stack
  1317                                  
  1318                                  D.D._ovl_mgr_code PROC    FAR
  1319                                  
  1320                                  ; kludge to allow checking for source id <> call code segment id
  1321                                  ; this is the case if an indirect call to overlay through a
  1322                                  ; memory location was set up in overlay class code and then the call
  1323                                  ; was made in a different segment than the setup segment
  1324                                  D.D._ovl_vector:
  1325 00000607 2EC606[3C00]01              mov byte [cs:D.D._ovl_in_manager], 1  ; flag used by profiler
  1326 0000060D 9C                          pushf                   ; save the flag register
  1327 0000060E 2E8F06[2200]                pop word [cs:flag_store]
  1328 00000613 F6C480                      test    ah,80h          ; see if far call
  1329 00000616 7419                        je  vect_1              ; no, near call, continue with normal code
  1330                                  
  1331                                  check_seg_id:
  1332 00000618 2E8F06[1A00]                pop word [cs:cx_store]         ; get cx,bx,ax original values in storage off of stack
  1333 0000061D 2E8F06[1800]                pop word [cs:bx_store]
  1334 00000622 2E8F06[1600]                pop word [cs:ax_store]
  1335 00000627 59                          pop cx                  ; get call offset in cx
  1336 00000628 2E8916[1C00]                mov [cs:dx_store],dx      ; save dx
  1337 0000062D 5A                          pop dx                  ; get calling segment value in dx
  1338                                  
  1339                                  ; ax holds proper overlaid public value from initial entry
  1340 0000062E E968FF                      jmp NEAR PTR ind_altent ; jump to code shared with indirect call routine
  1341                                  
  1342                                  vect_1:
  1343 00000631 2E890E[1400]                mov [cs:call_segment],cx  ; save segment of calling routine
  1344 00000636 2E891E[0E00]                mov [cs:source_id],bx     ; save id of calling routine
  1345 0000063B 2EA3[1000]                  mov [cs:destination_id],ax    ; save id of routine to call
  1346 0000063F 2E8F06[1A00]                pop word [cs:cx_store]         ; save cx,bx,ax original values
  1347 00000644 2E8F06[1800]                pop word [cs:bx_store]
  1348 00000649 2E8F06[1600]                pop word [cs:ax_store]
  1349 0000064E 2E8F06[1200]                pop word [cs:call_offset]
  1350                                  
  1351                                  ; alternate entry point for routine from $$_ovl_ind_2ovl_ent routine
  1352                                  vector_altent:
  1353                                  
  1354                                  ; save program's stack pointer and segment
  1355                                  vect_2:
  1356 00000653 8CD0                        mov ax,ss
  1357 00000655 89E3                        mov bx,sp               ; get program stack values
  1358 00000657 2EA3[0200]                  mov [cs:prog_ss_store],ax
  1359 0000065B 2E891E[0000]                mov [cs:prog_sp_store],bx ; save them
  1360                                  
  1361                                  ; set stack to overlay manager internal stack
  1362 00000660 BB[4001]                    mov bx,OFFSET D.D._ovl_mgr_stack_end
  1363 00000663 B8[ssss]                    mov ax,SEG D.D._ovl_mgr_stack_end
  1364 00000666 FA                          cli                     ; shut off interrupts while stack is set
  1365 00000667 8ED0                        mov ss,ax
  1366 00000669 89DC                        mov sp,bx               ; set internal stack
  1367 0000066B FB                          sti                     ; turn interrupts back on
  1368                                  
  1369 0000066C 2EA0[0F00]                  mov al,BYTE PTR [cs:source_id+1]
  1370 00000670 2440                        and al,40h              ; see if calling via external fixup reference
  1371 00000672 7413                        je  vect_2a             ; yes
  1372                                  
  1373                                  ; calling via segment fixup reference, use overlay identifier in destination_id
  1374                                  ; and use an offset of zero
  1375 00000674 31C0                        xor ax,ax               ; zero offset
  1376 00000676 2EA3[2400]                  mov [cs:jump_offset],ax   ; save it
  1377 0000067A 2EA1[1000]                  mov ax,[cs:destination_id]    ; get overlay identifier number
  1378 0000067E 25FF3F                      and ax,3fffh            ; maks off flag bits
  1379 00000681 2EA3[2600]                  mov [cs:jump_segment],ax  ; save segment
  1380 00000685 EB4F                        jmp SHORT vect_3        ; calling an overlay
  1381                                  
  1382                                  ; get target address segment:offset from lookup table
  1383                                  ; lookup table segment only used if called routine is not an overlay,
  1384                                  ; otherwise segment value is really the overlay identifier
  1385                                  vect_2a:
  1386 00000687 2E8B1E[1000]                mov bx,[cs:destination_id]
  1387 0000068C 81E3FF3F                    and bx,3fffh            ; mask off flag bits
  1388 00000690 4B                          dec bx                  ; make relative zero
  1389 00000691 D1E3                        shl bx,1
  1390 00000693 D1E3                        shl bx,1
  1391 00000695 D1E3                        shl bx,1                ; convert bx to quadword offset
  1392 00000697 1E                          push    ds              ; save data segment
  1393 00000698 2EA1[3000]                  mov ax,[cs:D.D._ovl_lookup_table]   ; get lookup table segment
  1394 0000069C 8ED8                        mov ds,ax
  1395                                  
  1396 0000069E 8B4704                      mov ax,[bx+4]           ; get offset to near vector routine of segment
  1397 000006A1 2EA3[2800]                  mov [cs:nearv_offset],ax  ; save offset to near vector routine
  1398                                  
  1399                                  ; add extra check for call from overlay to root, since indirect
  1400                                  ; overlay vector routine now used for that case with removal of far vectors
  1401                                  ; within a segment will not set the flag properly
  1402 000006A5 8A4706                      mov al,[bx+6]           ; get root called flag
  1403 000006A8 2E0806[1100]                or  BYTE PTR [cs:destination_id+1],al ; merge into source identifier
  1404                                  
  1405 000006AD C507                        lds ax,[bx]             ; get seg:off of target address in ds:ax
  1406 000006AF 2EA3[2400]                  mov [cs:jump_offset],ax   ; save offset
  1407 000006B3 8CD8                        mov ax,ds
  1408 000006B5 2EA3[2600]                  mov [cs:jump_segment],ax  ; save segment
  1409                                  
  1410 000006B9 1F                          pop ds                  ; restore data segment
  1411                                  
  1412 000006BA 2EA0[1100]                  mov al,BYTE PTR [cs:destination_id+1]
  1413 000006BE 2440                        and al,40h              ; see if calling an overlay
  1414 000006C0 7414                        je  vect_3              ; yes
  1415                                  
  1416                                  ; calling non-overlaid code, fixup the segment address
  1417 000006C2 2EA1[2A00]                  mov ax,[cs:prog_psp]      ; get PSP
  1418 000006C6 83C010                      add ax,10h              ; add 10h paragraphs to get load address
  1419 000006C9 2E0106[2600]                add [cs:jump_segment],ax  ; add to segment paragraph value
  1420 000006CE EB0F                        jmp SHORT vect_4        ; bypass overlaid code load check
  1421                                  
  1422                                  vect_stackerr:
  1423 000006D0 B80100                      mov ax,1                ; get error value in ax
  1424 000006D3 E9510C                      jmp NEAR PTR D.D._ovl_op_error    ; stack overflow
  1425                                  
  1426                                  vect_3:
  1427 000006D6 2EC606[3600]01              mov byte [cs:is_calling_ovl],1 ; flag that overlay being called
  1428 000006DC E82C02                      call    D.D._ovl_ready_overlay    ; load overlay if necessary, modify jump_segment
  1429                                  
  1430                                  ; set stack to calling routine seg/id/offset stack
  1431                                  vect_4:
  1432 000006DF 2E8B1E[0400]                mov bx,[cs:D.D._ovl_stack_ptr]
  1433 000006E4 83FB08                      cmp bx,8                ; check for stack overflow
  1434 000006E7 72E7                        jb  vect_stackerr       ; overflow
  1435                                  
  1436 000006E9 2EA1[0600]                  mov ax,[cs:D.D._ovl_stack_start]
  1437 000006ED FA                          cli                     ; shut off interrupts while stack is set
  1438 000006EE 8ED0                        mov ss,ax
  1439 000006F0 89DC                        mov sp,bx               ; set internal stack
  1440 000006F2 FB                          sti                     ; turn interrupts back on
  1441                                  
  1442 000006F3 2EFF36[1000]                push    word [cs:destination_id]   ; save destination routine, needed for reload option
  1443 000006F8 2EFF36[1400]                push    word [cs:call_segment] ; save segment to stack
  1444 000006FD 2EFF36[0E00]                push    word [cs:source_id]    ; save source id code to stack
  1445 00000702 2EFF36[1200]                push    word [cs:call_offset]
  1446 00000707 2E8926[0400]                mov [cs:D.D._ovl_stack_ptr],sp  ; save new stack pointer value
  1447                                  
  1448                                  ; restore stack to program value
  1449 0000070C 2EA1[0200]                  mov ax,[cs:prog_ss_store]
  1450 00000710 2E8B1E[0000]                mov bx,[cs:prog_sp_store] ; get stack entry values
  1451 00000715 FA                          cli                     ; shut off interrupts while stack is set
  1452 00000716 8ED0                        mov ss,ax
  1453 00000718 89DC                        mov sp,bx               ; set internal stack
  1454 0000071A FB                          sti                     ; turn interrupts back on
  1455                                  
  1456                                  ; restore ax,bx,cx to original values
  1457 0000071B 2E8B0E[1A00]                mov cx,[cs:cx_store]
  1458 00000720 2E8B1E[1800]                mov bx,[cs:bx_store]
  1459 00000725 2EA1[1600]                  mov ax,[cs:ax_store]
  1460                                  
  1461                                  ; profiler traps here to monitor calls
  1462                                  D.D._ovl_prof_call:
  1463 00000729 90                          nop
  1464                                  
  1465 0000072A 2EF606[1100]80              test    BYTE [cs:destination_id+1],80h    ; see if a far call
  1466 00000730 7413                        je  vect_near           ; no, near call
  1467                                  
  1468                                  ; far call from calling routine
  1469 00000732 2EFF36[2200]                push    word [cs:flag_store]   ; get original flag value
  1470 00000737 9D                          popf                    ; restore to flag word
  1471 00000738 2EC606[3C00]00              mov byte [cs:D.D._ovl_in_manager], 0  ; flag used by profiler
  1472 0000073E 2EFF1E[2400]                call    far [cs:jump_offset]    ; transfer control to overlay
  1473 00000743 EB20                        jmp SHORT D.D._ovl_ret    ; upon return, transfer to overlay manager return handler
  1474                                  
  1475                                  ; near call from calling routine
  1476                                  vect_near:
  1477 00000745 2EFF36[2200]                push    word [cs:flag_store]   ; get original flag value
  1478 0000074A 9D                          popf                    ; restore to flag word
  1479 0000074B 2EFF36[2400]                push    word [cs:jump_offset]  ; put offset on stack for overlay's near vector routine use
  1480 00000750 2EFF36[2800]                push    word [cs:nearv_offset] ; get offset to near vector routine for segment
  1481 00000755 2E8F06[2400]                pop word [cs:jump_offset]      ; replace jump address offset
  1482 0000075A 2EC606[3C00]00              mov byte [cs:D.D._ovl_in_manager], 0  ; flag used by profiler
  1483 00000760 2EFF2E[2400]                jmp far [cs:jump_offset]    ; transfer control to overlay's near vector routine
  1484                                  
  1485                                  D.D._ovl_mgr_code ENDP
  1486                                  
  1487                                  ;*****************************
  1488                                  ;* $$_OVL_MGR_RET            *
  1489                                  ;*****************************
  1490                                  
  1491                                  D.D._ovl_mgr_ret  PROC    FAR
  1492                                  
  1493                                  D.D._ovl_ret:
  1494 00000765 2EC606[3C00]01              mov byte [cs:D.D._ovl_in_manager], 1  ; flag used by profiler
  1495 0000076B 2E890E[1A00]                mov [cs:cx_store],cx      ; save original ax,bx,cx
  1496 00000770 2E891E[1800]                mov [cs:bx_store],bx
  1497 00000775 2EA3[1600]                  mov [cs:ax_store],ax
  1498 00000779 9C                          pushf                   ; save the flag register
  1499 0000077A 2E8F06[2200]                pop word [cs:flag_store]
  1500                                  
  1501                                  ; save program's stack pointer and segment
  1502 0000077F 8CD0                        mov ax,ss
  1503 00000781 89E3                        mov bx,sp               ; get program stack values
  1504 00000783 2EA3[0200]                  mov [cs:prog_ss_store],ax
  1505 00000787 2E891E[0000]                mov [cs:prog_sp_store],bx ; save them
  1506                                  
  1507                                  ; set stack to calling routine seg/id/offset stack
  1508 0000078C 2E8B1E[0400]                mov bx,[cs:D.D._ovl_stack_ptr]
  1509 00000791 2EA1[0600]                  mov ax,[cs:D.D._ovl_stack_start]
  1510 00000795 FA                          cli                     ; shut off interrupts while stack is set
  1511 00000796 8ED0                        mov ss,ax
  1512 00000798 89DC                        mov sp,bx               ; set internal stack
  1513 0000079A FB                          sti                     ; turn interrupts back on
  1514                                  
  1515 0000079B 2E8F06[1200]                pop word [cs:call_offset]      ; get calling routine's offset
  1516 000007A0 2E8F06[0E00]                pop word [cs:source_id]        ; get calling routine's identification
  1517 000007A5 2E8F06[1400]                pop word [cs:call_segment]     ; get calling routine's segment  (changed for return to overlay)
  1518 000007AA 2E8F06[1000]                pop word [cs:destination_id]   ; get called routine's identification
  1519 000007AF 2E8926[0400]                mov [cs:D.D._ovl_stack_ptr],sp  ; save new stack pointer value
  1520                                  
  1521 000007B4 2EC606[3600]00              mov byte [cs:is_calling_ovl], 0  ; only the profiler cares about this right now
  1522                                  
  1523 000007BA 2E803E[3400]00              cmp byte [cs:D.D._ovl_reload_flag],0 ; see if reload overlay option in effect
  1524 000007C0 7415                        je  omr_2               ; no, bypass reload overlay stack adjustment
  1525                                  
  1526 000007C2 2EA0[1100]                  mov al,BYTE PTR [cs:destination_id+1]
  1527 000007C6 2440                        and al,40h              ; see if root was called
  1528 000007C8 7403                        je  ovl_called          ; no
  1529 000007CA E98F00                      jmp NEAR PTR omr_3      ; yes
  1530                                  
  1531                                  ; overlay called with reload option, extra info on stack
  1532                                  ovl_called:
  1533 000007CD 2E8F06[3200]                pop word [cs:D.D._ovl_stackcount]
  1534 000007D2 2E8926[0400]                mov [cs:D.D._ovl_stack_ptr],sp  ; save new stack pointer value
  1535                                  
  1536                                  ; set stack to overlay manager internal stack
  1537                                  omr_2:
  1538 000007D7 BB[4001]                    mov bx,OFFSET D.D._ovl_mgr_stack_end
  1539 000007DA B8[ssss]                    mov ax,SEG D.D._ovl_mgr_stack_end
  1540 000007DD FA                          cli                     ; shut off interrupts while stack is set
  1541 000007DE 8ED0                        mov ss,ax
  1542 000007E0 89DC                        mov sp,bx               ; set internal stack
  1543 000007E2 FB                          sti                     ; turn interrupts back on
  1544                                  
  1545 000007E3 2EA0[3400]                  mov al,[cs:D.D._ovl_reload_flag]
  1546 000007E7 08C0                        or  al,al               ; see if reload overlay option in effect
  1547 000007E9 7471                        je  omr_3               ; no, bypass reload specific code
  1548                                  
  1549                                  ; drop activity level of overlay
  1550 000007EB 1E                          push    ds              ; save critical register
  1551 000007EC B9[ssss]                    mov cx,D.D._ovl_data      ; save -> overlay manager data
  1552                                  
  1553 000007EF 2EA0[0F00]                  mov al,BYTE PTR [cs:source_id+1]
  1554 000007F3 2440                        and al,40h              ; see if called via external fixup reference
  1555 000007F5 7409                        je  deact_2             ; yes
  1556                                  
  1557                                  ; called via segment fixup reference,overlay identifier in destination_id
  1558 000007F7 2EA1[1000]                  mov ax,[cs:destination_id]    ; get overlay identifier number
  1559 000007FB 25FF3F                      and ax,3fffh            ; mask off flag bits
  1560 000007FE EB18                        jmp SHORT deact_3       ; bypass overlay identifier computation
  1561                                  
  1562                                  ; get overlay identifier lookup table
  1563                                  deact_2:
  1564 00000800 2E8B1E[1000]                mov bx,[cs:destination_id]
  1565 00000805 81E3FF3F                    and bx,3fffh            ; mask off flag bits
  1566 00000809 4B                          dec bx                  ; make relative zero
  1567 0000080A D1E3                        shl bx,1
  1568 0000080C D1E3                        shl bx,1
  1569 0000080E D1E3                        shl bx,1                ; convert bx to quadword offset
  1570 00000810 2E8E1E[3000]                mov ds,[cs:D.D._ovl_lookup_table]   ; get lookup table segment
  1571 00000815 8B4702                      mov ax,[bx+2]           ; get overlay identifier
  1572                                  
  1573                                  ; overlay identifer in ax, search the overlays loaded array to find it
  1574                                  deact_3:
  1575 00000818 2E833E[4400]00              cmp word [cs:last_access_slot],0
  1576 0000081E 740B                        je  deact_4
  1577 00000820 2E8E1E[4400]                mov ds,[cs:last_access_slot]  ; ds -> last access overlay slot
  1578 00000825 3B060000                    cmp ax,[0]           ; see if id matches last accessed id
  1579 00000829 7413                        je  deact_found         ; yes, update the array element
  1580                                  
  1581                                  deact_4:
  1582 0000082B 8ED9                        mov ds,cx               ; ds -> overlay manager data
  1583 0000082D 8B1E[0401]                  mov bx,[D.D._ovl_array_start]
  1584 00000831 8EDB                        mov ds,bx                   ; ds -> overlay array
  1585                                  
  1586                                  deact_loop:
  1587 00000833 3B060000                    cmp ax,[0]           ; see if array element matches
  1588 00000837 7405                        je  deact_found         ; yes, update the array element
  1589 00000839 43                          inc bx
  1590 0000083A 8EDB                        mov ds,bx
  1591 0000083C EBF5                        jmp SHORT deact_loop    ; loop until overlay is found
  1592                                  
  1593                                  deact_found:
  1594 0000083E FF0E0400                    dec WORD PTR [4]     ; drop activity level
  1595                                  
  1596 00000842 2E833E[3200]00              cmp word [cs:D.D._ovl_stackcount],0  ; see if any overlays to restore
  1597 00000848 7411                        je  omr_2a              ; no
  1598                                  
  1599                                  ; this overlay will be swapped out by the overlays that it swapped out
  1600                                  ; zero the array entry and drop the overlays loaded count
  1601 0000084A 31C0                        xor ax,ax
  1602 0000084C A30000                      mov [0],ax
  1603 0000084F A30400                      mov [4],ax           ; zero activity level
  1604                                  
  1605 00000852 8ED9                        mov ds,cx               ; ds -> overlay manager data
  1606 00000854 FF0E[2201]                  dec word [D.D._ovl_loaded_count] ; drop count of loaded overlays to reflect terminated overlay swapout
  1607 00000858 E85D09                      call    D.D._ovl_swap_in  ; load the swapped out active overlays
  1608                                  
  1609                                  omr_2a:
  1610 0000085B 1F                          pop ds                  ; restore critical register
  1611                                  
  1612                                  omr_3:
  1613 0000085C 2EA0[0F00]                  mov al,BYTE PTR [cs:source_id+1]
  1614 00000860 2480                        and al,80h              ; see if calling routine was in root
  1615 00000862 7450                        je  omr_4               ; no
  1616                                  
  1617                                  ; calling routine was in root
  1618 00000864 1E                          push    ds
  1619 00000865 56                          push    si
  1620 00000866 52                          push    dx
  1621 00000867 B8[ssss]                    mov ax,D.D._ovl_data
  1622 0000086A 8ED8                        mov ds,ax               ; ds -> overlay manager data
  1623 0000086C 8B0E[2201]                  mov cx,[D.D._ovl_loaded_count]
  1624 00000870 8E1E[0401]                  mov ds,[D.D._ovl_array_start]   ; ds -> overlay loaded array
  1625 00000874 31C0                        xor ax,ax
  1626 00000876 89C3                        mov bx,ax
  1627 00000878 89C2                        mov dx,ax
  1628 0000087A 2EA3[4400]                  mov [cs:last_access_slot],ax
  1629                                  
  1630                                  last_access_loop:
  1631 0000087E 3B060000                    cmp ax,[0]           ; see if unused array element
  1632 00000882 7422                        je  next_access_check   ; yes
  1633 00000884 49                          dec cx                  ; drop count of active overlays checked
  1634 00000885 3B060400                    cmp ax,[4]           ; see if active overlay
  1635 00000889 741B                        je  next_access_check   ; no
  1636 0000088B 3B160C00                    cmp dx,[12]          ; see if have higher LRU active
  1637 0000088F 7715                        ja  next_access_check   ; yes
  1638 00000891 7206                        jb  new_last_access     ; no
  1639 00000893 3B1E0A00                    cmp bx,[10]          ; equal, check higher LRU low word
  1640 00000897 770D                        ja  next_access_check
  1641                                  
  1642                                  new_last_access:
  1643 00000899 2E8C1E[4400]                mov [cs:last_access_slot],ds  ; keep highest LRU active
  1644 0000089E 8B160C00                	mov	dx,[12]
  1645 000008A2 8B1E0A00                	mov	bx,[10]
  1646                                  
  1647                                  next_access_check:
  1648 000008A6 8CDE                        mov si,ds
  1649 000008A8 46                          inc si
  1650 000008A9 8EDE                        mov ds,si
  1651 000008AB 09C9                        or  cx,cx
  1652 000008AD 75CF                        jne last_access_loop
  1653                                  
  1654 000008AF 5A                          pop dx
  1655 000008B0 5E                          pop si
  1656 000008B1 1F                          pop ds
  1657                                  
  1658 000008B2 EB28                        jmp NEAR PTR mgret_exit
  1659                                  
  1660                                  ; set stack to overlay manager internal stack in case of call to root bypassing first stack set
  1661                                  omr_4:
  1662 000008B4 BB[4001]                    mov bx,OFFSET D.D._ovl_mgr_stack_end
  1663 000008B7 B8[ssss]                    mov ax,SEG D.D._ovl_mgr_stack_end
  1664 000008BA FA                          cli                     ; shut off interrupts while stack is set
  1665 000008BB 8ED0                        mov ss,ax
  1666 000008BD 89DC                        mov sp,bx               ; set internal stack
  1667 000008BF FB                          sti                     ; turn interrupts back on
  1668                                  
  1669 000008C0 2EA1[0E00]                  mov ax,[cs:source_id]     ; get source id
  1670 000008C4 25FF3F                      and ax,3fffh            ; strip off flag bits
  1671 000008C7 2EA3[2600]                  mov [cs:jump_segment],ax  ; place in jump_segment for get overlay ready routine
  1672                                  
  1673 000008CB 2EC606[3600]00              mov byte [cs:is_calling_ovl],0 ; flag that overlay being returned from
  1674 000008D1 E83700                      call    D.D._ovl_ready_overlay    ; load overlay if necessary, modify jump_segment
  1675                                  
  1676 000008D4 2EA1[2600]                  mov ax,[cs:jump_segment]  ; get jump segment in call segment for return
  1677 000008D8 2EA3[1400]                  mov [cs:call_segment],ax
  1678                                  
  1679                                  ; restore stack to program values, restore registers, and return
  1680                                  mgret_exit:
  1681 000008DC 2EA1[0200]                  mov ax,[cs:prog_ss_store]
  1682 000008E0 2E8B1E[0000]                mov bx,[cs:prog_sp_store] ; get stack entry values
  1683 000008E5 FA                          cli                     ; shut off interrupts while stack is set
  1684 000008E6 8ED0                        mov ss,ax
  1685 000008E8 89DC                        mov sp,bx               ; set internal stack
  1686 000008EA FB                          sti                     ; turn interrupts back on
  1687                                  
  1688                                  ; profiler traps this point to monitor returns
  1689                                  D.D._ovl_prof_return:
  1690 000008EB 90                          nop
  1691                                  
  1692 000008EC 2E8B0E[1A00]                mov cx,[cs:cx_store]
  1693 000008F1 2E8B1E[1800]                mov bx,[cs:bx_store]
  1694 000008F6 2EA1[1600]                  mov ax,[cs:ax_store]
  1695 000008FA 2EFF36[2200]                push    word [cs:flag_store]   ; get original flag value
  1696 000008FF 9D                          popf                    ; restore to flag word
  1697 00000900 2EC606[3C00]00              mov byte [cs:D.D._ovl_in_manager], 0  ; flag used by profiler
  1698                                  
  1699 00000906 2EFF2E[1200]                jmp far [cs:call_offset]    ; transfer back to calling routine
  1700                                  
  1701                                  D.D._ovl_mgr_ret  ENDP
  1702                                  
  1703                                  ;*****************************
  1704                                  ;* $$_OVL_READY_OVERLAY      *
  1705                                  ;*****************************
  1706                                  
  1707                                  ; load overlay, if necessary
  1708                                  ; upon entry jump_segment holds overlay identifier
  1709                                  ; update LRU counter of overlay
  1710                                  ; update jump_segment to overlay's current segment
  1711                                  ; destroys ax,bx,cx
  1712                                  ;
  1713                                  ; Format of loaded overlay array structure:
  1714                                  ;   Overlay identification number   DW  ?
  1715                                  ;   Unused                          DW  ?
  1716                                  ;   Activity level, 0 if not active DW  ?
  1717                                  ;   Overlay segment/start para      DW  ?
  1718                                  ;   Overlay ending paragraph        DW  ?
  1719                                  ;   LRU counter value               DD  ?
  1720                                  ;   Filler to pad to one paragraph  DW  ?
  1721                                  
  1722                                  D.D._ovl_ready_overlay    PROC    NEAR
  1723 0000090B 1E                          push    ds              ; save critical registers
  1724 0000090C 06                          push    es
  1725 0000090D 52                          push    dx
  1726 0000090E B8[ssss]                    mov ax,D.D._ovl_data
  1727 00000911 8ED8                        mov ds,ax               ; ds -> overlay manager data
  1728                                  
  1729 00000913 833E[2201]00                cmp word [D.D._ovl_loaded_count],0   ; see if any overlays loaded
  1730 00000918 743A                        je  ready_must_load     ; no, first overlay must always be loaded
  1731                                  
  1732                                  ; look for loaded overlay entry
  1733                                  ready_look:
  1734 0000091A 2E8B1E[2600]                mov bx,[cs:jump_segment]  ; get identification number to match against in bx
  1735 0000091F 2E833E[4400]00              cmp word [cs:last_access_slot],0
  1736 00000925 740C                        je  ready_1
  1737 00000927 2E8E06[4400]                mov es,[cs:last_access_slot]  ; es -> last access overlay slot
  1738 0000092C 263B1E0000                  cmp bx,[es:0]           ; see if id matches last accessed id
  1739 00000931 7439                        je  ready_match         ; yes
  1740                                  
  1741                                  ready_1:
  1742 00000933 A1[0401]                    mov ax,[D.D._ovl_array_start]
  1743 00000936 8EC0                        mov es,ax
  1744 00000938 31C9                        xor cx,cx               ; cx == number of loaded overlays found
  1745                                  
  1746                                  ready_loop:
  1747 0000093A 26A10000                    mov ax,[es:0]           ; get overlay identification number
  1748 0000093E 39D8                        cmp ax,bx               ; see if a match
  1749 00000940 742A                        je  ready_match         ; yes
  1750                                  
  1751                                  ; no match try next entry, if any
  1752 00000942 09C0                        or  ax,ax               ; see if loaded overlay in this entry
  1753 00000944 7507                        jne ready_3             ; yes
  1754                                  
  1755                                  ready_2:
  1756 00000946 8CC0                        mov ax,es               ; get old entry segment
  1757 00000948 40                          inc ax
  1758 00000949 8EC0                        mov es,ax               ; bump to next entry
  1759 0000094B EBED                        jmp SHORT ready_loop    ; check next entry for match
  1760                                  
  1761                                  ready_3:
  1762 0000094D 41                          inc cx                  ; increment count of loaded overlays found
  1763 0000094E 3B0E[2201]                  cmp cx,[D.D._ovl_loaded_count]  ; see if all loaded overlays checked
  1764 00000952 72F2                        jb  ready_2             ; no, move to next entry
  1765                                  
  1766                                  ; overlay must be loaded
  1767                                  ready_must_load:
  1768 00000954 E89203                      call    D.D._ovl_get_info     ; get overlay system information from file
  1769 00000957 E8B800                      call    D.D._ovl_find_slot    ; find the best overlay pool slot to load overlay
  1770 0000095A E8D305                      call    D.D._ovl_load_overlay ; load overlay at segment found
  1771 0000095D FF06[2201]                  inc word [D.D._ovl_loaded_count]     ; increment count of loaded overlays
  1772 00000961 A1[3E01]                    mov ax,[D.D._ovl_load_seg]
  1773 00000964 EB4E                        jmp SHORT ready_loaded      ; bypass already loaded code
  1774                                  
  1775                                  ready_stackerr:
  1776 00000966 B80100                      mov ax,1                ; get error value in ax
  1777 00000969 E9BB09                      jmp NEAR PTR D.D._ovl_op_error    ; stack overflow
  1778                                  
  1779                                  ; entry matches this overlay
  1780                                  ready_match:
  1781 0000096C 2E803E[3400]00              cmp byte [cs:D.D._ovl_reload_flag],0 ; see if reload overlays option is in effect
  1782 00000972 7437                        je  match_2             ; no
  1783                                  
  1784 00000974 2E803E[3600]00              cmp byte [cs:is_calling_ovl],0 ; see if calling overlay
  1785 0000097A 7434                        je  match_3             ; no, returning from overlay, bypass activity level update
  1786                                  
  1787                                  ; calling an already loaded overlay
  1788                                  ; push a zero on the overlay stack for number of overlays swapped out
  1789                                  
  1790                                  ; set stack to calling routine seg/id/offset stack
  1791 0000097C 2E8926[0800]                mov [cs:D.D._ovl_mgr_stack_ptr],sp  ; first save current stack pointer
  1792 00000981 2E8B16[0400]                mov dx,[cs:D.D._ovl_stack_ptr]
  1793 00000986 83FA02                      cmp dx,2                ; must be room for zero
  1794 00000989 72DB                        jb  ready_stackerr      ; not enough room
  1795                                  
  1796                                  match_1:
  1797 0000098B 2EA1[0600]                  mov ax,[cs:D.D._ovl_stack_start]
  1798 0000098F FA                          cli                     ; shut off interrupts while stack is set
  1799 00000990 8ED0                        mov ss,ax
  1800 00000992 89D4                        mov sp,dx               ; set stack
  1801 00000994 FB                          sti                     ; turn interrupts back on
  1802 00000995 31C0                        xor ax,ax               ; put zero on stack
  1803 00000997 50                          push    ax
  1804 00000998 2E8926[0400]                mov [cs:D.D._ovl_stack_ptr],sp  ; save new stack pointer value
  1805                                  
  1806                                  ; reset stack to overlay manager internal stack
  1807 0000099D 2E8B16[0800]                mov dx,[cs:D.D._ovl_mgr_stack_ptr]
  1808 000009A2 B8[ssss]                    mov ax,SEG D.D._ovl_mgr_stack_end
  1809 000009A5 FA                          cli                     ; shut off interrupts while stack is set
  1810 000009A6 8ED0                        mov ss,ax
  1811 000009A8 89D4                        mov sp,dx               ; set internal stack
  1812 000009AA FB                          sti                     ; turn interrupts back on
  1813                                  
  1814                                  match_2:
  1815 000009AB 26FF060400                  inc WORD PTR [es:4]     ; bump activity level
  1816                                  
  1817                                  match_3:
  1818 000009B0 26A10600                    mov ax,[es:6]           ; get overlay segment
  1819                                  
  1820                                  ; overlay loaded
  1821                                  ; es -> array element of loaded overlay
  1822                                  ready_loaded:
  1823 000009B4 2EA3[2600]                  mov [cs:jump_segment],ax  ; update jump_segment
  1824                                  
  1825                                  ; save last accessed overlay
  1826 000009B8 2E8C06[4400]                mov [cs:last_access_slot],es  ; save last access slot
  1827                                  
  1828 000009BD A1[F800]                    mov ax,WORD PTR [D.D._ovl_lru_counter]  ; get old counter value low word
  1829 000009C0 83C001                      add ax,1
  1830 000009C3 A3[F800]                    mov WORD PTR [D.D._ovl_lru_counter],ax  ; update low word
  1831 000009C6 8316[FA00]00                adc WORD [D.D._ovl_lru_counter+2],0 ; carry to high word
  1832 000009CB 8B1E[FA00]                  mov bx,WORD PTR [D.D._ovl_lru_counter+2]    ; get counter value high word
  1833 000009CF 26A30A00                    mov [es:10],ax          ; update overlay loaded array LRU low word
  1834 000009D3 26891E0C00                  mov [es:12],bx          ; update high word
  1835 000009D8 09D8                        or  ax,bx               ; check if lru counter overflow
  1836 000009DA 7404                        je  lru_overflow        ; yes
  1837                                  
  1838                                  ready_ret:
  1839 000009DC 5A                          pop dx                  ; restore critical registers
  1840 000009DD 07                          pop es
  1841 000009DE 1F                          pop ds
  1842 000009DF C3                          ret
  1843                                  
  1844                                  ; lru counter overflowed, reset counters in all array entries
  1845                                  lru_overflow:
  1846 000009E0 40                          inc ax
  1847 000009E1 A3[F800]                    mov WORD PTR [D.D._ovl_lru_counter],ax  ; reset lru counter to 1
  1848                                  
  1849                                  ; cycle through all entries, setting the lru counter to zero
  1850 000009E4 A1[0401]                    mov ax,[D.D._ovl_array_start]
  1851 000009E7 8EC0                        mov es,ax
  1852 000009E9 31C0                        xor ax,ax
  1853 000009EB 8B0E[FC00]                  mov cx,[D.D._ovl_max_load]
  1854                                  
  1855                                  ready_zero_loop:
  1856 000009EF 26A30A00                    mov [es:10],ax          ; zero lru low word
  1857 000009F3 26A30C00                    mov [es:12],ax          ; zero lru high word
  1858 000009F7 8CC3                        mov bx,es
  1859 000009F9 43                          inc bx
  1860 000009FA 8EC3                        mov es,bx               ; move to next entry
  1861 000009FC E2F1                        loop    ready_zero_loop ; loop until done
  1862 000009FE EBDC                        jmp SHORT ready_ret
  1863                                  
  1864                                  D.D._ovl_ready_overlay    ENDP
  1865                                  
  1866                                  ;*****************************
  1867                                  ;* $$_OVL_FIND_SLOT          *
  1868                                  ;*****************************
  1869                                  
  1870                                  ; find best place to load overlay in overlay pool, based on
  1871                                  ; lru counter values and number of overlays swapped out.
  1872                                  ; lowest LRU value has precedence over count swapped.
  1873                                  ; cs:jump_segment variable holds overlay identifier
  1874                                  ; returns load segment in $$_ovl_load_seg
  1875                                  ; returns load array element in es
  1876                                  ; destroys ax,bx,cx,dx,es
  1877                                  
  1878                                  ; no overlays loaded
  1879                                  no_ovl_loaded:
  1880 00000A00 2EA1[0A00]                  mov ax,[cs:D.D._ovl_load_start]
  1881 00000A04 A3[3E01]                    mov [D.D._ovl_load_seg],ax  ; use start of load area for load segment
  1882 00000A07 89C2                        mov dx,ax               ; dx holds start paragraph
  1883 00000A09 8B1E[3401]                  mov bx,[ofh_ovl_size]
  1884 00000A0D 01D3                        add bx,dx               ; bx holds end paragraph
  1885 00000A0F E98402                      jmp NEAR PTR slot_ret   ; bypass search for area to load
  1886                                  
  1887                                  D.D._ovl_find_slot    PROC    NEAR
  1888 00000A12 1E                          push    ds              ; save critical register
  1889 00000A13 56                          push    si
  1890 00000A14 57                          push    di
  1891 00000A15 8B36[0401]                  mov si,[D.D._ovl_array_start]   ; si holds array element for new overlay
  1892 00000A19 31C0                        xor ax,ax
  1893 00000A1B 2EA3[3200]                  mov [cs:D.D._ovl_stackcount],ax ; init count of overlays on stack
  1894 00000A1F 3906[2201]                  cmp [D.D._ovl_loaded_count],ax  ; see if any overlays loaded
  1895 00000A23 74DB                        je  no_ovl_loaded       ; no
  1896                                  
  1897                                  ;********** start rewrite
  1898                                  
  1899                                  %if 0 ; COMMENT #
  1900                                      mov ax,WORD PTR $$_ovl_pool+1   ; get count of words*2 in check array
  1901                                      shr ax,1                ; compute count of words in check array
  1902                                      mov cx,ax
  1903                                      add ax,ax               ; get number of bytes in check array
  1904                                      mov check_array_size,ax ; keep it
  1905                                      xor ax,ax
  1906                                      mov di,ax
  1907                                      mov es,check_array
  1908                                      rep stosw               ; clear the check array
  1909                                  END COMMENT #
  1910                                  %endif ; COMMENT end
  1911                                  
  1912                                  ; 9/2/92
  1913 00000A25 8B0E[5801]                  mov cx,[check_array_size]	; get number of bytes in check array
  1914 00000A29 D1E9                    	shr	cx,1				; convert to words
  1915 00000A2B 31C0                        xor ax,ax
  1916 00000A2D 89C7                        mov di,ax
  1917 00000A2F 8E06[F70B]                  mov es,[check_array]
  1918 00000A33 F3AB                        rep stosw               ; clear the check array
  1919                                  
  1920 00000A35 8B0E[2201]                  mov cx,[D.D._ovl_loaded_count]  ; get count of loaded overlays
  1921 00000A39 1E                          push    ds              ; save -> manager data
  1922 00000A3A 8EDE                        mov ds,si               ; ds -> overlay loaded array
  1923                                  
  1924                                  ; es -> check array
  1925                                  check_loop:
  1926 00000A3C A10000                      mov ax,[0]           ; get overlay identifier number
  1927 00000A3F 09C0                        or  ax,ax               ; see if zero
  1928 00000A41 7448                        je  next_check          ; yes, try next element
  1929 00000A43 49                          dec cx                  ; drop count of overlays to check
  1930 00000A44 8CDA                        mov dx,ds
  1931 00000A46 2E3B16[4400]                cmp dx,[cs:last_access_slot]  ; see if this is last accessed overlay
  1932 00000A4B 7505                        jne check_2             ; no
  1933 00000A4D 80CC80                      or ah,80h               ; flag last accessed overlay
  1934 00000A50 EB11                        jmp SHORT store_value
  1935                                  
  1936                                  check_2:
  1937 00000A52 833E040000                  cmp WORD PTR [4],0   ; see if an active overlay
  1938 00000A57 7405                        je  store_inactive      ; no
  1939 00000A59 80CC40                      or  ah,40h              ; flag active overlay
  1940 00000A5C EB05                        jmp SHORT store_value
  1941                                  
  1942                                  ; store slot pointer, not overlay id
  1943                                  store_inactive:
  1944 00000A5E 8CD8                        mov ax,ds
  1945 00000A60 29F0                        sub ax,si               ; subtract start of array
  1946 00000A62 40                          inc ax                  ; make relative 1
  1947                                  
  1948                                  store_value:
  1949 00000A63 8B160800                    mov dx,[8]
  1950 00000A67 8B3E0600                    mov di,[6]
  1951 00000A6B 29FA                        sub dx,di               ; get size of overlay
  1952 00000A6D 83C21F                      add dx,1fh              ; round up to next 512 byte boundary (in paras)
  1953 00000A70 D1EA                        shr dx,1
  1954 00000A72 D1EA                        shr dx,1
  1955 00000A74 D1EA                        shr dx,1
  1956 00000A76 D1EA                        shr dx,1
  1957 00000A78 D1EA                        shr dx,1                ; convert to 512 byte chunks
  1958 00000A7A 2E2B3E[0A00]                sub di,[cs:D.D._ovl_load_start] ; di -> para offset of overlay start
  1959 00000A7F D1EF                        shr di,1
  1960 00000A81 D1EF                        shr di,1
  1961 00000A83 D1EF                        shr di,1
  1962 00000A85 D1EF                        shr di,1                ; convert para offset to 512 word (256 byte) offset
  1963                                  
  1964                                  store_loop:
  1965 00000A87 AB                          stosw                   ; save modified overlay id
  1966 00000A88 4A                          dec dx                  ; drop count of 512 byte overlay chunks
  1967 00000A89 75FC                        jne store_loop          ; save until all chunks represented
  1968                                  
  1969                                  next_check:
  1970 00000A8B E307                        jcxz    store_done      ; more more loaded overlays to check
  1971 00000A8D 8CD8                        mov ax,ds
  1972 00000A8F 40                          inc ax
  1973 00000A90 8ED8                        mov ds,ax               ; ds -> next overlay loaded array element
  1974 00000A92 EBA8                        jmp SHORT check_loop
  1975                                  
  1976                                  store_done:
  1977 00000A94 1F                          pop ds                  ; restore ds -> manager data
  1978                                  
  1979 00000A95 B8FFFF                      mov ax,0ffffh
  1980 00000A98 A3[4401]                    mov [D.D._ovl_best_count],ax    ; set best count such that any count of swapped overlays is better than init value
  1981                                  ;***    mov $$_ovl_best_active,ax   ; init best active swapout count high
  1982 00000A9B A3[4A01]                    mov WORD PTR [D.D._ovl_hi_best_lru],ax  ; init so any comparison will have lower LRU
  1983 00000A9E A3[4C01]                    mov WORD PTR [D.D._ovl_hi_best_lru+2],ax
  1984 00000AA1 A3[5601]                    mov [ovl_best_size],ax    ; init best load size so fails on any comparison
  1985 00000AA4 8E06[F70B]                  mov es,[check_array]
  1986 00000AA8 31F6                        xor si,si               ; es:si -> check array
  1987                                  
  1988 00000AAA 8B16[3401]                  mov dx,[ofh_ovl_size]     ; get overlay file size in paragraphs
  1989 00000AAE 83C21F                      add dx,1fh              ; round up to next 512 byte boundary (in paras)
  1990 00000AB1 B105                        mov cl,5
  1991 00000AB3 D3EA                        shr dx,cl               ; convert to 512 byte chunks
  1992                                  
  1993                                  main_check_loop:
  1994 00000AB5 31C0                        xor ax,ax
  1995 00000AB7 A3[4001]                    mov [D.D._ovl_swap_count],ax    ; init count of overlays swapped by proposed load position
  1996                                  ;***    mov $$_ovl_swap_active,ax   ; init count of active overlays swapped by proposed load
  1997 00000ABA A3[4601]                    mov WORD PTR [D.D._ovl_highest_lru],ax  ; init so any comparison will force a higher LRU
  1998 00000ABD A3[4801]                    mov WORD PTR [D.D._ovl_highest_lru+2],ax
  1999 00000AC0 A3[5401]                    mov [ovl_act_size],ax     ; init size of active swapouts
  2000 00000AC3 89F3                        mov bx,si               ; offset into check_array
  2001                                  
  2002                                  block_check_loop:
  2003 00000AC5 268B07                      mov ax,[es:bx]          ; get overlay id/slot #
  2004 00000AC8 F6C480                      test    ah,80h          ; see if last used overlay
  2005 00000ACB 7526                        jne to_bump_proposed    ; yes, don't use this position
  2006 00000ACD 09C0                        or  ax,ax               ; see if used
  2007 00000ACF 746F                        je  check_next_block    ; no, try next block in overlay, if any
  2008                                  
  2009 00000AD1 FF06[4001]                  inc word [D.D._ovl_swap_count]   ; bump count of overlays swapped out
  2010 00000AD5 F6C440                      test    ah,40h
  2011 00000AD8 7423                        je  check_inactive      ; inactive overlay swapped out
  2012                                  
  2013                                  ; active overlay swapout at this position
  2014                                  ;***    inc $$_ovl_swap_active  ; bump count of active overlays swapped out
  2015 00000ADA FF06[5401]                  inc word [ovl_act_size]        ; bump load size by fake amount to compensate for each discrete active overlay
  2016                                  
  2017                                  check_act_loop:
  2018 00000ADE FF06[5401]                  inc word [ovl_act_size]        ; bump load size in 512 byte blocks
  2019 00000AE2 3B1E[5801]                  cmp bx,[check_array_size] ; see if at end
  2020 00000AE6 730E                        jae check_chunk_count   ; yes
  2021 00000AE8 263B4702                    cmp ax,[es:bx+2]        ; see if next chunk matches this
  2022 00000AEC 7508                        jne check_chunk_count   ; no
  2023 00000AEE 4A                          dec dx                  ; drop count of chunks to check
  2024 00000AEF 43                          inc bx
  2025 00000AF0 43                          inc bx
  2026 00000AF1 EBEB                        jmp SHORT check_act_loop    ; loop until end 
  2027                                  
  2028                                  to_bump_proposed:
  2029 00000AF3 E99C00                      jmp NEAR PTR bump_proposed
  2030                                  
  2031                                  check_chunk_count:
  2032 00000AF6 83FA00                      cmp dx,0                ; see if all of overlay used up (could be negative)
  2033 00000AF9 7E4A                        jle check_next_pos
  2034 00000AFB EB43                        jmp SHORT check_next_block  ; more positions to check for proposed overlay
  2035                                  
  2036                                  ; inactive overlay swapout
  2037                                  check_inactive:
  2038 00000AFD 48                          dec ax                  ; make slot # relative zero
  2039 00000AFE 0306[0401]                  add ax,[D.D._ovl_array_start]
  2040 00000B02 8EC0                        mov es,ax               ; es -> inactive overlay array entry
  2041 00000B04 26A10C00                    mov ax,[es:12]          ; get LRU counter high word
  2042 00000B08 3B06[4801]                  cmp ax,WORD PTR [D.D._ovl_highest_lru+2]    ; compare to previous lowest LRU high word
  2043 00000B0C 721A                        jb  no_update           ; lower than previous highest, don't update
  2044 00000B0E 770A                        ja  update_high_lru     ; higher than previous highest, update
  2045 00000B10 26A10A00                    mov ax,[es:10]          ; get LRU counter low word
  2046 00000B14 3B06[4601]                  cmp ax,WORD PTR [D.D._ovl_highest_lru]  ; compare to previous lowest LRU low word
  2047 00000B18 720E                        jb  no_update           ; lower than previous, don't update
  2048                                  
  2049                                  ; update the highest LRU values
  2050                                  update_high_lru:
  2051 00000B1A 26A10A00                    mov ax,[es:10]
  2052 00000B1E A3[4601]                    mov WORD PTR [D.D._ovl_highest_lru],ax  ; update low word
  2053 00000B21 26A10C00                    mov ax,[es:12]
  2054 00000B25 A3[4801]                    mov WORD PTR [D.D._ovl_highest_lru+2],ax    ; update high word
  2055                                  
  2056                                  ; no update or already performed drop-through
  2057                                  no_update:
  2058 00000B28 8E06[F70B]                  mov es,[check_array]
  2059 00000B2C 268B07                      mov ax,[es:bx]          ; get slot # in ax
  2060                                  
  2061                                  check_inact_loop:
  2062 00000B2F 3B1E[5801]                  cmp bx,[check_array_size] ; see if at end
  2063 00000B33 73C1                        jae check_chunk_count   ; yes
  2064 00000B35 263B4702                    cmp ax,[es:bx+2]        ; see if next chunk matches this
  2065 00000B39 75BB                        jne check_chunk_count   ; no
  2066 00000B3B 4A                          dec dx                  ; drop count of chunks to check
  2067 00000B3C 43                          inc bx
  2068 00000B3D 43                          inc bx
  2069 00000B3E EBEF                        jmp SHORT check_inact_loop  ; loop until end 
  2070                                  
  2071                                  check_next_block:
  2072 00000B40 43                          inc bx
  2073 00000B41 43                          inc bx                  ; bump word offset in check array
  2074 00000B42 4A                          dec dx                  ; drop count of chunks to check
  2075 00000B43 7580                        jne block_check_loop    ; more chunks to check
  2076                                  
  2077                                  check_next_pos:
  2078 00000B45 833E[4001]00                cmp word [D.D._ovl_swap_count],0 ; if zero swapped overlays, use this position
  2079 00000B4A 7462                        je  perfect_swap
  2080                                  
  2081                                  ; current position has overlays being swapped out
  2082 00000B4C A1[5601]                    mov ax,[ovl_best_size]    ; get best load size
  2083 00000B4F 3B06[5401]                  cmp ax,[ovl_act_size]
  2084 00000B53 723D                        jb  bump_proposed       ; best has less overlay loads than highest
  2085 00000B55 771F                        ja  best_update         ; current has least overlay movement, update best position
  2086                                  
  2087                                  ; best position and current position have same active load size,
  2088                                  ; check LRU for highest inactive, keep the lowest
  2089 00000B57 A1[4C01]                    mov ax,WORD PTR [D.D._ovl_hi_best_lru+2]    ; get high word of best highest LRU
  2090 00000B5A 3B06[4801]                  cmp ax,WORD PTR [D.D._ovl_highest_lru+2]    ; compare to lowest LRU this pass
  2091 00000B5E 7232                        jb  bump_proposed       ; best below lowest, don't update
  2092 00000B60 7714                        ja  best_update         ; best above highest, update position
  2093 00000B62 A1[4A01]                    mov ax,WORD PTR [D.D._ovl_hi_best_lru]  ; get low word of best LRU
  2094 00000B65 3B06[4601]                  cmp ax,WORD PTR [D.D._ovl_highest_lru]  ; compare to low word of this pass LRU
  2095 00000B69 7227                        jb  bump_proposed       ; best below lowest, don't update
  2096 00000B6B 7709                        ja  best_update         ; best above lowest, update position
  2097                                  
  2098                                  ; LRU's match, compare swap counts, use lowest
  2099 00000B6D A1[4401]                    mov ax,WORD PTR [D.D._ovl_best_count]
  2100 00000B70 3B06[4001]                  cmp ax,WORD PTR [D.D._ovl_swap_count]
  2101 00000B74 721C                        jb  bump_proposed       ; best swap count lower than current, don't update
  2102                                  
  2103                                  ; update best load position variables
  2104                                  best_update:
  2105 00000B76 A1[4801]                    mov ax,WORD PTR [D.D._ovl_highest_lru+2]
  2106 00000B79 A3[4C01]                    mov WORD PTR [D.D._ovl_hi_best_lru+2],ax    ; update high word of best LRU
  2107 00000B7C A1[4601]                    mov ax,WORD PTR [D.D._ovl_highest_lru]
  2108 00000B7F A3[4A01]                    mov WORD PTR [D.D._ovl_hi_best_lru],ax  ; update low word of best LRU
  2109                                  
  2110 00000B82 A1[4001]                    mov ax,[D.D._ovl_swap_count]
  2111 00000B85 A3[4401]                    mov [D.D._ovl_best_count],ax    ; update count of swapped overlays
  2112 00000B88 A1[5401]                    mov ax,[ovl_act_size]
  2113 00000B8B A3[5601]                    mov [ovl_best_size],ax    ; update best load size
  2114 00000B8E 8936[4201]                  mov [D.D._ovl_best_load],si ; save check array pointer new best load position
  2115                                  
  2116                                  bump_proposed:
  2117 00000B92 46                          inc si
  2118 00000B93 46                          inc si                  ; bump base check address
  2119 00000B94 89F0                        mov ax,si
  2120 00000B96 8B16[3401]                  mov dx,[ofh_ovl_size]     ; get overlay file size in paragraphs
  2121 00000B9A 83C21F                      add dx,1fh              ; round up to next 512 byte boundary (in paras)
  2122 00000B9D B105                        mov cl,5
  2123 00000B9F D3EA                        shr dx,cl               ; convert to 512 byte chunks
  2124 00000BA1 01D0                        add ax,dx               ; get final check array element
  2125 00000BA3 01D0                        add ax,dx               ; adjust for word count
  2126 00000BA5 3B06[5801]                  cmp ax,[check_array_size] ; see if past end
  2127 00000BA9 7730                        ja  swap_ovls           ; last overlay area that fits was checked
  2128 00000BAB E907FF                      jmp NEAR PTR main_check_loop    ; more overlay positions to check
  2129                                  
  2130                                  ; no overlays swapped at this position, use it
  2131                                  perfect_swap:
  2132 00000BAE 89F0                        mov ax,si               ; get current check array position word
  2133 00000BB0 B104                        mov cl,4
  2134 00000BB2 D3E0                        shl ax,cl               ; convert to paras (x16)
  2135 00000BB4 2E0306[0A00]                add ax,[cs:D.D._ovl_load_start] ; get real address
  2136 00000BB9 A3[3E01]                    mov [D.D._ovl_load_seg],ax  ; save load position
  2137 00000BBC 89C2                        mov dx,ax               ; dx holds start segment of overlay to load
  2138 00000BBE 8B1E[3401]                  mov bx,[ofh_ovl_size]     ; get overlay file size in paragraphs
  2139 00000BC2 01D3                        add bx,dx               ; bx holds end segment of overlay to load
  2140 00000BC4 8E06[0401]                  mov es,[D.D._ovl_array_start]   ; es -> overlay loaded array
  2141                                  
  2142                                  find_zero:
  2143 00000BC8 268B360000                  mov si,[es:0]           ; get overlay identifier of array element
  2144 00000BCD 09F6                        or  si,si               ; see if zero
  2145 00000BCF 7503                        jne find_2              ; no, keep looking
  2146 00000BD1 E9C400                      jmp NEAR PTR slot_ret2  ; yes, use this array element (es->array element)
  2147                                  
  2148                                  find_2:
  2149 00000BD4 8CC0                        mov ax,es
  2150 00000BD6 40                          inc ax
  2151 00000BD7 8EC0                        mov es,ax               ; bump to next array element
  2152 00000BD9 EBED                        jmp SHORT find_zero     ; keep looking for unused array element
  2153                                  
  2154                                  swap_ovls:
  2155 00000BDB A1[4201]                    mov ax,[D.D._ovl_best_load] ; get best check array position word
  2156 00000BDE B104                        mov cl,4
  2157 00000BE0 D3E0                        shl ax,cl               ; convert to paras (x16)
  2158 00000BE2 2E0306[0A00]                add ax,[cs:D.D._ovl_load_start] ; get real address
  2159 00000BE7 A3[3E01]                    mov [D.D._ovl_load_seg],ax  ; use best proposed load area for load segment
  2160 00000BEA 89C2                        mov dx,ax               ; dx holds start segment of overlay to load
  2161 00000BEC 8B1E[3401]                  mov bx,[ofh_ovl_size]     ; get overlay file size in paragraphs
  2162 00000BF0 01D3                        add bx,dx               ; bx holds end segment of overlay to load
  2163 00000BF2 8E06[0401]                  mov es,[D.D._ovl_array_start]   ; es -> overlay array
  2164 00000BF6 8B0E[4401]                  mov cx,[D.D._ovl_best_count]    ; get count of overlays to swap out
  2165                                  
  2166 00000BFA 83F9FF                  	cmp	cx,-1				; see if best never init'ed (only last overlay exists)
  2167 00000BFD 7503                    	jne	zero_loop			; no
  2168 00000BFF B90100                  	mov	cx,1				; change to one overlay to swapout
  2169                                  
  2170                                  ;********** end rewrite
  2171                                  
  2172                                  zero_loop:
  2173 00000C02 26A10000                    mov ax,[es:0]           ; get overlay identifier number
  2174 00000C06 09C0                        or  ax,ax               ; see if nonzero
  2175 00000C08 7509                        jne zero_2              ; nonzero, valid overlay
  2176 00000C0A 8CC6                        mov si,es               ; si -> empty slot
  2177                                  
  2178 00000C0C 09C9                        or  cx,cx               ; see if more overlays to swap out
  2179 00000C0E 757E                        jne next_element        ; yes
  2180 00000C10 E98300                      jmp NEAR PTR slot_ret   ; any and all necessary overlays swapped out
  2181                                  
  2182                                  zero_2:
  2183 00000C13 E379                        jcxz    next_element    ; no overlays to swap, just looking for empty slot
  2184 00000C15 263B160800                  cmp dx,[es:8]           ; check proposed start against overlay end
  2185 00000C1A 7372                        jae next_element        ; above end, overlay not swapped
  2186 00000C1C 263B1E0600                  cmp bx,[es:6]           ; check proposed end against overlay start
  2187 00000C21 766B                        jbe next_element        ; below start, overlay not swapped
  2188                                  
  2189 00000C23 2E803E[3400]00              cmp byte [cs:D.D._ovl_reload_flag],0 ; see if reload overlays option in effect
  2190 00000C29 7450                        je  zero_3              ; no
  2191                                  
  2192 00000C2B 26A10400                    mov ax,[es:4]
  2193 00000C2F 09C0                        or  ax,ax               ; see if active overlay
  2194 00000C31 744A                        je  zero_4              ; no
  2195                                  
  2196                                  ; set stack to calling routine seg/id/activity stack
  2197 00000C33 2E8926[0800]                mov [cs:D.D._ovl_mgr_stack_ptr],sp  ; first save current stack pointer
  2198 00000C38 2E8B3E[0400]                mov di,[cs:D.D._ovl_stack_ptr]
  2199 00000C3D 2EA1[0600]                  mov ax,[cs:D.D._ovl_stack_start]
  2200 00000C41 FA                          cli                     ; shut off interrupts while stack is set
  2201 00000C42 8ED0                        mov ss,ax
  2202 00000C44 89FC                        mov sp,di               ; set internal stack
  2203 00000C46 FB                          sti                     ; turn interrupts back on
  2204 00000C47 26FF360600                  push    word [es:6]          ; save load segment to stack
  2205 00000C4C 26FF360000                  push    word [es:0]          ; save overlay identifier to stack
  2206 00000C51 26FF360A00                  push    word [es:10]         ; save LRU low word
  2207 00000C56 26FF360C00                  push    word [es:12]         ; save LRU high word
  2208 00000C5B 26FF360400                  push    word [es:4]          ; save activity level
  2209                                  
  2210 00000C60 2EFF06[3200]                inc word [cs:D.D._ovl_stackcount]    ; bump count of overlays saved to stack
  2211 00000C65 2E8926[0400]                mov [cs:D.D._ovl_stack_ptr],sp  ; save new stack pointer value
  2212                                  
  2213                                  ; set stack to overlay manager internal stack
  2214 00000C6A 2E8B3E[0800]                mov di,[cs:D.D._ovl_mgr_stack_ptr]
  2215 00000C6F B8[ssss]                    mov ax,SEG D.D._ovl_mgr_stack_end
  2216 00000C72 FA                          cli                     ; shut off interrupts while stack is set
  2217 00000C73 8ED0                        mov ss,ax
  2218 00000C75 89FC                        mov sp,di               ; set internal stack
  2219 00000C77 FB                          sti                     ; turn interrupts back on
  2220                                  
  2221 00000C78 E8FA0A                      call    chk_xmsems_swapout  ; see if can swapout to XMS/EMS
  2222                                  
  2223                                  zero_3:
  2224 00000C7B 31C0                        xor ax,ax
  2225                                  
  2226                                  zero_4:
  2227 00000C7D 26A30000                    mov [es:0],ax           ; zero overlay identifier for this array element
  2228 00000C81 26A30400                    mov [es:4],ax           ; zero activity level
  2229                                  
  2230 00000C85 8CC6                        mov si,es               ; si -> empty slot
  2231 00000C87 FF0E[2201]                  dec word [D.D._ovl_loaded_count] ; drop count of loaded overlays
  2232 00000C8B 49                          dec cx                  ; drop count of overlays left to swap out
  2233 00000C8C E308                        jcxz    slot_ret        ; any and all necessary overlays swapped out, si -> empty slot
  2234                                  
  2235                                  next_element:
  2236 00000C8E 8CC0                        mov ax,es               ; get array element segment
  2237 00000C90 40                          inc ax                  ; bump to next element
  2238 00000C91 8EC0                        mov es,ax               ; update array element pointer
  2239 00000C93 E96CFF                      jmp NEAR PTR zero_loop  ; loop back to check next array element for zero'ing
  2240                                  
  2241                                  slot_ret:
  2242 00000C96 8EC6                        mov es,si               ; es -> overlay loaded array element for new overlay
  2243                                  
  2244                                  slot_ret2:
  2245 00000C98 2E803E[3400]00              cmp byte [cs:D.D._ovl_reload_flag],0     ; see if reload overlays option in effect
  2246 00000C9E 742C                        je  slot_ret3           ; no
  2247                                  
  2248                                  ; set stack to calling routine seg/id/offset stack
  2249 00000CA0 2E8926[0800]                mov [cs:D.D._ovl_mgr_stack_ptr],sp  ; first save current stack pointer
  2250 00000CA5 2E8B3E[0400]                mov di,[cs:D.D._ovl_stack_ptr]
  2251 00000CAA 2EA1[0600]                  mov ax,[cs:D.D._ovl_stack_start]
  2252 00000CAE FA                          cli                     ; shut off interrupts while stack is set
  2253 00000CAF 8ED0                        mov ss,ax
  2254 00000CB1 89FC                        mov sp,di               ; set internal stack
  2255 00000CB3 FB                          sti                     ; turn interrupts back on
  2256                                  
  2257 00000CB4 2EFF36[3200]                push    word [cs:D.D._ovl_stackcount]    ; put count of active overlays swapped out on stack
  2258 00000CB9 2E8926[0400]                mov [cs:D.D._ovl_stack_ptr],sp  ; save new stack pointer value
  2259                                  
  2260                                  ; reset stack to overlay manager internal stack
  2261 00000CBE 2E8B3E[0800]                mov di,[cs:D.D._ovl_mgr_stack_ptr]
  2262 00000CC3 B8[ssss]                    mov ax,SEG D.D._ovl_mgr_stack_end
  2263 00000CC6 FA                          cli                     ; shut off interrupts while stack is set
  2264 00000CC7 8ED0                        mov ss,ax
  2265 00000CC9 89FC                        mov sp,di               ; set internal stack
  2266 00000CCB FB                          sti                     ; turn interrupts back on
  2267                                  
  2268                                  slot_ret3:
  2269 00000CCC 2EA1[2600]                  mov ax,[cs:jump_segment]  ; get overlay identifier
  2270 00000CD0 26A30000                    mov [es:0],ax
  2271 00000CD4 2689160600                  mov [es:6],dx           ; save start paragraph
  2272 00000CD9 26891E0800                  mov [es:8],bx           ; save end paragraph
  2273                                  
  2274 00000CDE 26C70604000100              mov WORD PTR [es:4],1   ; set activity level to 1 (first time active)
  2275                                  
  2276                                  slot_ret4:
  2277 00000CE5 5F                          pop di
  2278 00000CE6 5E                          pop si
  2279 00000CE7 1F                          pop ds                  ; restore critical register
  2280 00000CE8 C3                          ret
  2281                                  D.D._ovl_find_slot    ENDP
  2282                                  
  2283                                  ;***********************************************************
  2284                                  
  2285                                  ; all overlays concatenated in one .OVL file, 
  2286                                  ; each rounded to nearest paragraph
  2287                                  ; OVL file format:
  2288                                  ;   Count of overlays           DW  ?
  2289                                  ;   Offset to overlay 1         DD  ?
  2290                                  ;       ...
  2291                                  ;   Offset to overlay n         DD  ?
  2292                                  ;   Overlay files
  2293                                  ;
  2294                                  ; Overlay file format in .OVL file
  2295                                  ;   Overlay number              DW  ?
  2296                                  ;   Offset to overlay code      DW  ?
  2297                                  ;   Overlay code size in paras  DW  ?
  2298                                  ;   Offset to near/shared vectors   DW  ?
  2299                                  ;   Relocation entry count      DW  ?
  2300                                  ;   Relocation entry 1          DW  ?
  2301                                  ;       ...
  2302                                  ;   Relocation entry n          DW  ?
  2303                                  ;   Overlay code begins
  2304                                  
  2305                                  ;***********************************************************
  2306                                  
  2307                                  ;*****************************
  2308                                  ;* $$_OVL_GET_INFO           *
  2309                                  ;*****************************
  2310                                  
  2311                                  ; get overlay file system information
  2312                                  ; jump_segment variable holds overlay identifier
  2313                                  ; destroys ax,bx,cx,dx
  2314                                  
  2315                                  D.D._ovl_get_info PROC    NEAR
  2316 00000CE9 C606[8409]00            	mov	byte [info_from_emsxms_flag],0	; init overlay stashed in EMS/XMS flag
  2317                                  
  2318                                  err_retry6:
  2319 00000CEE 1E                      	push	ds				; save -> overlay manager data
  2320 00000CEF 2E8B1E[2600]                mov bx,[cs:jump_segment]  ; get overlay identifier
  2321 00000CF4 4B                          dec bx                  ; make relative zero
  2322 00000CF5 D1E3                        shl bx,1                ; make doubleword offset into file position table
  2323 00000CF7 D1E3                        shl bx,1
  2324 00000CF9 8E1E[0A01]                  mov ds,[D.D._ovl_filepos]   ; ds -> overlay file position table
  2325 00000CFD 8B17                        mov dx,[bx]             ; get file position
  2326 00000CFF 8B4F02                      mov cx,[bx+2]
  2327 00000D02 1F                      	pop	ds					;  restore ds -> overlay manager data
  2328 00000D03 8916[1E01]                  mov WORD PTR [D.D._ovl_file_offset],dx  ; save position low word
  2329 00000D07 890E[2001]                  mov WORD PTR [D.D._ovl_file_offset+2],cx    ; save  position high word
  2330                                  
  2331                                  ; check if can load from overlay file stashed in EMS or XMS
  2332 00000D0B F6C5C0                  	test	ch,0c0h			; see if two high bits set (file stash to EMS/XMS)
  2333 00000D0E 7404                    	je	ogi_seek			; no
  2334 00000D10 E82700                  	call	ovl_emsxms_get_info	; get info from EMS or XMS
  2335 00000D13 C3                      	ret
  2336                                  
  2337                                  ; seek to overlay file in OVL file
  2338                                  ; dx:cx already set to proper values
  2339                                  ogi_seek:
  2340 00000D14 8B1E[2401]                  mov bx,[D.D._ovl_file_handle]
  2341 00000D18 B80042                      mov ax,4200h            ; move file pointer, relative beginning of file
  2342 00000D1B CD21                        int 21h
  2343 00000D1D 7305                        jnc read_sys
  2344                                  
  2345 00000D1F E87605                      call NEAR PTR D.D._ovl_dos_error
  2346 00000D22 EBCA                        jmp SHORT err_retry6
  2347                                  
  2348                                  ; read system information for overlay file (first 5 words)
  2349                                  read_sys:
  2350 00000D24 8B1E[2401]                  mov bx,[D.D._ovl_file_handle]
  2351 00000D28 B90A00                      mov cx,10               ; read 10 bytes
  2352 00000D2B BA[3001]                    mov dx,OFFSET D.D._ovl_file_header    ; read overlay file header bytes
  2353 00000D2E B43F                        mov ah,3fh              ; read file
  2354 00000D30 CD21                        int 21h
  2355 00000D32 7305                        jnc ogi_ret             ; no error
  2356                                  
  2357 00000D34 E86105                      call NEAR PTR D.D._ovl_dos_error
  2358 00000D37 EBEB                        jmp SHORT read_sys
  2359                                  
  2360                                  ogi_ret:
  2361 00000D39 C3                          ret
  2362                                  
  2363                                  D.D._ovl_get_info ENDP
  2364                                  
  2365                                  ;*****************************
  2366                                  ;* OVL_EMSXMS_GET_INFO       *
  2367                                  ;*****************************
  2368                                  
  2369                                  ; get overlay file system information from EMS or XMS
  2370                                  ; upon entry jump_segment variable holds overlay identifier,
  2371                                  ;   two MSB of ch flag whether XMS (80h) or EMS(40h) stashing
  2372                                  ;   $$_ovl_file_offset holds offset with EMS/XMS
  2373                                  ; destroys ax,bx,cx,dx
  2374                                  
  2375                                  ovl_emsxms_get_info	PROC	NEAR
  2376 00000D3A 56                      	push	si				; save critical register
  2377 00000D3B 57                      	push	di
  2378 00000D3C 882E[8409]              	mov	[info_from_emsxms_flag],ch	; set overlay stashed in EMS/XMS flag
  2379                                  
  2380 00000D40 8CDA                    	mov	dx,ds
  2381 00000D42 BF[3001]                    mov di,OFFSET D.D._ovl_file_header
  2382 00000D45 B90A00                  	mov	cx,10				; count of chars to transfer
  2383 00000D48 8B36[1E01]              	mov	si,WORD PTR [D.D._ovl_file_offset]	; source offset
  2384 00000D4C 8B1E[2001]              	mov	bx,WORD PTR [D.D._ovl_file_offset+2]	; logical page number/high word source offset
  2385 00000D50 80E73F                  	and	bh,3fh				; mask off EMS/XMS flag bits
  2386                                  
  2387                                  ; bx==logical page number (EMS)/high word source offset (XMS)
  2388                                  ; cx==count of chars to transfer
  2389                                  ; dx==destination segment
  2390                                  ; si==source offset
  2391                                  ; di==destination offset
  2392 00000D53 E80300                  	call	ovl_emsxms_read	; read in the info from EMS/XMS
  2393                                  
  2394                                  oeg_ret:
  2395 00000D56 5F                      	pop	di					; restore critical register
  2396 00000D57 5E                      	pop	si
  2397 00000D58 C3                      	ret
  2398                                  ovl_emsxms_get_info	ENDP
  2399                                  
  2400                                  ;*****************************
  2401                                  ;* OVL_EMSXMS_READ           *
  2402                                  ;*****************************
  2403                                  
  2404                                  ; read from EMS/XMS to conventional memory
  2405                                  ; upon entry:
  2406                                  ;   bx==logical page number (EMS)/high byte source offset (XMS)
  2407                                  ;   cx==count of chars to transfer
  2408                                  ;   dx==destination segment
  2409                                  ;   si==source offset
  2410                                  ;   di==destination offset
  2411                                  ; destroys ax,bx,cx,dx,si,di
  2412                                  
  2413                                  ovl_emsxms_read	PROC	NEAR
  2414 00000D59 06                      	push	es				; save critical register
  2415 00000D5A 8EC2                    	mov	es,dx				; es -> destination
  2416 00000D5C 8B16[9B0B]              	mov	dx,[ohpoht_handle]	; get source handle
  2417 00000D60 F606[8409]80            	test	byte [info_from_emsxms_flag],80h	; see if XMS flag set
  2418 00000D65 7432                    	je	ord_ems				; no, get from EMS
  2419                                  
  2420 00000D67 890E[BB0B]              	mov	WORD PTR [ohtbuff + os_len],cx	; length of block
  2421 00000D6B 8936[C10B]              	mov	WORD PTR [ohtbuff + os_src_offset],si	; offset of source, low word
  2422 00000D6F 881E[C30B]              	mov	BYTE PTR [ohtbuff + os_src_offset+2],bl	; offset of source, high word low byte
  2423 00000D73 8916[BF0B]              	mov	[ohtbuff + os_src_handle],dx	; source handle
  2424 00000D77 893E[C70B]                  mov WORD PTR [ohtbuff + os_dest_offset],di	; destination low word offset (offset)
  2425 00000D7B 8C06[C90B]                  mov WORD PTR [ohtbuff + os_dest_offset+2],es	; destination high word offset (segment)
  2426 00000D7F 31C0                    	xor	ax,ax
  2427 00000D81 A3[BD0B]                	mov	WORD PTR [ohtbuff + os_len+2],ax	; zero high word of length
  2428 00000D84 A2[C40B]                	mov	BYTE PTR [ohtbuff + os_src_offset+3],al	; zero high byte of source offset
  2429 00000D87 A3[C50B]                	mov	[ohtbuff + os_dest_handle],ax	; zero destination handle (conventional memory)
  2430                                  
  2431 00000D8A B40B                        mov ah,0bh				; move extended memory block
  2432 00000D8C BE[BB0B]                    mov si,OFFSET ohtbuff	; ds:si -> parameter block
  2433 00000D8F FF1E[9D0B]                  call    far [xms_addr]
  2434 00000D93 E8C10B                      call    check_xms_error	; see if error occurred
  2435 00000D96 E98D00                  	jmp	NEAR PTR ord_ret
  2436                                  
  2437                                  ord_ems:
  2438 00000D99 803E[8309]00            	cmp	byte [D.D._ems3_flag],0		; see if using EMS 3.0 compatibility
  2439 00000D9E 7542                    	jne	ord_ems3			; yes
  2440                                  
  2441 00000DA0 890E[DD0B]              	mov	WORD PTR [ohpbuff + os_len],cx	; length of block
  2442 00000DA4 C606[E10B]01            	mov	byte [ohpbuff + os_stype],1	; expanded memory source type
  2443 00000DA9 8916[E20B]              	mov	[ohpbuff + os_shandle],dx	; source handle
  2444 00000DAD 891E[E60B]              	mov	[ohpbuff + os_ssegpage],bx	; logical page number
  2445                                  
  2446                                  ord_loop:
  2447 00000DB1 81FE0040                	cmp	si,4000h			; see if page overflow
  2448 00000DB5 720A                    	jb	ord_off
  2449 00000DB7 81EE0040                	sub	si,4000h			; drop offset
  2450 00000DBB FF06[E60B]              	inc	word [ohpbuff + os_ssegpage]	; increase logical page number
  2451 00000DBF EBF0                    	jmp	SHORT ord_loop		; drop until si is in range
  2452                                  
  2453                                  ord_off:
  2454 00000DC1 8936[E40B]              	mov	[ohpbuff + os_soffset],si	; offset of source
  2455                                  
  2456 00000DC5 893E[EB0B]              	mov	[ohpbuff + os_doffset],di	; destination offset
  2457 00000DC9 8C06[ED0B]              	mov	[ohpbuff + os_dsegpage],es	; destination segment
  2458 00000DCD 31C0                    	xor	ax,ax
  2459 00000DCF A2[E80B]                	mov	[ohpbuff + os_dtype],al	; conventional memory destination type
  2460 00000DD2 A3[E90B]                	mov	[ohpbuff + os_dhandle],ax	; destination handle
  2461                                  
  2462 00000DD5 B80057                      mov ax,5700h			; move memory region
  2463 00000DD8 BE[DD0B]                    mov si,OFFSET ohpbuff	; ds:si -> parameter block
  2464 00000DDB CD67                        int 67h
  2465 00000DDD E8880B                  	call	check_ems_error
  2466 00000DE0 EB44                    	jmp	SHORT ord_ret
  2467                                  
  2468                                  ; bx==logical page number
  2469                                  ; cx==count of chars to transfer
  2470                                  ; dx==handle of EMS page
  2471                                  ; si==source offset
  2472                                  ; es==destination segment
  2473                                  ; di==destination offset
  2474                                  ord_ems3:
  2475 00000DE2 B447                    	mov	ah,47h				; save page map
  2476 00000DE4 CD67                        int 67h
  2477 00000DE6 E87F0B                  	call	check_ems_error
  2478 00000DE9 1E                      	push	ds				; save -> overlay manager data
  2479 00000DEA 8E1E[8E09]              	mov	ds,[D.D._ovl_ems_base]	; ds:si -> source
  2480                                  
  2481                                  ord_map:
  2482 00000DEE B80044                      mov ax,4400h			; map expanded memory page to page 0
  2483 00000DF1 CD67                        int 67h
  2484 00000DF3 E8720B                  	call	check_ems_error
  2485                                  
  2486                                  ; copy to destination
  2487 00000DF6 89C8                    	mov	ax,cx
  2488 00000DF8 01F0                    	add	ax,si
  2489 00000DFA 3D0040                  	cmp	ax,4000h			; see if overflow to next page
  2490 00000DFD 7617                    	jbe	ord_noover			; no
  2491                                  
  2492                                  ; transfer to end of page
  2493 00000DFF B80040                  	mov	ax,4000h
  2494 00000E02 29F0                    	sub	ax,si				; get chars to transfer for this page
  2495 00000E04 29C1                    	sub	cx,ax				; update total transferred char count
  2496 00000E06 91                      	xchg	ax,cx			; ax==total transfer char count, cx==page transfer char count
  2497 00000E07 D1E9                        shr cx,1                ; convert byte count to write to words
  2498 00000E09 F3A5                        rep movsw               ; move the string
  2499 00000E0B D1D1                        rcl cx,1                ; pick up carry
  2500 00000E0D F3A4                        rep movsb               ; transfer leftover byte, if any
  2501 00000E0F 89C1                    	mov	cx,ax				; total transfer char count back in cx
  2502                                  
  2503 00000E11 43                      	inc	bx					; move to next logical page
  2504 00000E12 31F6                    	xor	si,si				; zero offset on next page
  2505 00000E14 EBD8                    	jmp	SHORT ord_map		; do next page transfer
  2506                                  
  2507                                  ord_noover:
  2508 00000E16 D1E9                        shr cx,1                ; convert byte count to write to words
  2509 00000E18 F3A5                        rep movsw               ; move the string
  2510 00000E1A D1D1                        rcl cx,1                ; pick up carry
  2511 00000E1C F3A4                        rep movsb               ; transfer leftover byte, if any
  2512                                  
  2513 00000E1E B448                    	mov	ah,48h				; restore page map
  2514 00000E20 CD67                        int 67h
  2515 00000E22 E8430B                  	call	check_ems_error
  2516 00000E25 1F                      	pop	ds					; restore ds -> overlay manager data
  2517                                  
  2518                                  ord_ret:
  2519 00000E26 07                      	pop	es					; restore critical register
  2520 00000E27 C3                      	ret
  2521                                  ovl_emsxms_read	ENDP
  2522                                  
  2523                                  ;*****************************
  2524                                  ;* OVL_EMSXMS_WRITE          *
  2525                                  ;*****************************
  2526                                  
  2527                                  ; write from conventional memory to EMS/XMS
  2528                                  ; upon entry:
  2529                                  ;   cx==count of chars to transfer
  2530                                  ;   di==destination offset relative to emsxms_offset start position
  2531                                  ;   si==source offset
  2532                                  ;   dx==source segment
  2533                                  ; destroys ax,bx,cx,dx,si,di
  2534                                  
  2535                                  ovl_emsxms_write	PROC	NEAR
  2536 00000E28 8B1E[9B0B]              	mov	bx,[ohpoht_handle]	; get source handle
  2537 00000E2C 803E[7F09]00            	cmp	byte [D.D._ovl_oht],0		; see if stashing to XMS
  2538 00000E31 7439                    	je	owr_ems				; no, write to EMS
  2539                                  
  2540 00000E33 890E[BB0B]              	mov	WORD PTR [ohtbuff + os_len],cx	; length of block
  2541 00000E37 891E[C50B]              	mov	[ohtbuff + os_dest_handle],bx	; destination handle
  2542 00000E3B 8936[C10B]                  mov WORD PTR [ohtbuff + os_src_offset],si	; source low word offset (offset)
  2543 00000E3F 8916[C30B]                  mov WORD PTR [ohtbuff + os_src_offset+2],dx	; source high word offset (segment)
  2544 00000E43 A1[A90B]                	mov	ax,WORD PTR [emsxms_offset+2]
  2545 00000E46 033E[A70B]              	add	di,WORD PTR [emsxms_offset]	; compute destination offset
  2546 00000E4A 83D000                  	adc	ax,0
  2547 00000E4D 893E[C70B]              	mov	WORD PTR [ohtbuff + os_dest_offset],di	; offset of destination, low word
  2548 00000E51 A2[C90B]                	mov	BYTE PTR [ohtbuff + os_dest_offset+2],al	; offset of destination, high word low byte
  2549 00000E54 31C0                    	xor	ax,ax
  2550 00000E56 A3[BD0B]                	mov	WORD PTR [ohtbuff + os_len+2],ax	; zero high word of length
  2551 00000E59 A2[CA0B]                	mov	BYTE PTR [ohtbuff + os_dest_offset+3],al	; zero high byte of destination offset
  2552 00000E5C A3[BF0B]                	mov	[ohtbuff + os_src_handle],ax	; zero source handle (conventional memory)
  2553                                  
  2554 00000E5F B40B                        mov ah,0bh				; move extended memory block
  2555 00000E61 BE[BB0B]                    mov si,OFFSET ohtbuff	; ds:si -> parameter block
  2556 00000E64 FF1E[9D0B]                  call    far [xms_addr]
  2557 00000E68 E8EC0A                      call    check_xms_error	; see if error occurred
  2558 00000E6B C3                      	ret
  2559                                  
  2560                                  owr_ems:
  2561 00000E6C 803E[8309]00            	cmp	byte [D.D._ems3_flag],0		; see if using EMS 3.0 compatibility
  2562 00000E71 7557                    	jne	owr_ems3			; yes
  2563                                  
  2564 00000E73 890E[DD0B]              	mov	WORD PTR [ohpbuff + os_len],cx	; length of block
  2565 00000E77 C606[E80B]01            	mov	byte [ohpbuff + os_dtype],1	; expanded memory destination type
  2566 00000E7C 891E[E90B]              	mov	[ohpbuff + os_dhandle],bx	; destination handle
  2567 00000E80 8936[E40B]              	mov	[ohpbuff + os_soffset],si	; source offset
  2568 00000E84 8916[E60B]              	mov	[ohpbuff + os_ssegpage],dx	; source segment
  2569 00000E88 8B16[A90B]              	mov	dx,WORD PTR [emsxms_offset+2]
  2570 00000E8C A1[A70B]                	mov	ax,WORD PTR [emsxms_offset]
  2571 00000E8F 01F8                    	add	ax,di				; add in offset
  2572 00000E91 83D200                  	adc	dx,0
  2573 00000E94 89C3                    	mov	bx,ax
  2574 00000E96 80E43F                  	and	ah,3fh				; mask to 16K page
  2575 00000E99 D1E3                    	shl	bx,1				; convert bytes in dx:bx to page with remainder truncation
  2576 00000E9B D1D2                    	rcl	dx,1
  2577 00000E9D D1E3                    	shl	bx,1
  2578 00000E9F D1D2                    	rcl	dx,1				; dx==page number
  2579 00000EA1 8916[ED0B]              	mov	[ohpbuff + os_dsegpage],dx	; logical page number
  2580                                  
  2581                                  owr_loop:
  2582 00000EA5 3D0040                  	cmp	ax,4000h			; see if page overflow
  2583 00000EA8 7209                    	jb	owr_off
  2584 00000EAA 2D0040                  	sub	ax,4000h			; drop offset
  2585 00000EAD FF06[ED0B]              	inc	word [ohpbuff + os_dsegpage]	; increase logical page number
  2586 00000EB1 EBF2                    	jmp	SHORT owr_loop		; drop until si is in range
  2587                                  
  2588                                  owr_off:
  2589 00000EB3 A3[EB0B]                	mov	[ohpbuff + os_doffset],ax	; offset of destination
  2590                                  
  2591 00000EB6 31C0                    	xor	ax,ax
  2592 00000EB8 A2[E10B]                	mov	[ohpbuff + os_stype],al	; conventional memory source type
  2593 00000EBB A3[E20B]                	mov	[ohpbuff + os_shandle],ax	; source handle
  2594                                  
  2595 00000EBE B80057                      mov ax,5700h			; move memory region
  2596 00000EC1 BE[DD0B]                    mov si,OFFSET ohpbuff	; ds:si -> parameter block
  2597 00000EC4 CD67                        int 67h
  2598 00000EC6 E89F0A                  	call	check_ems_error
  2599 00000EC9 C3                      	ret
  2600                                  
  2601                                  ; cx==count of chars to transfer
  2602                                  ; bx==handle of EMS page
  2603                                  ; si==source offset
  2604                                  ; di==destination offset
  2605                                  ; dx==source segment
  2606                                  owr_ems3:
  2607 00000ECA 06                      	push	es				; save critical register
  2608 00000ECB 8EC2                    	mov	es,dx				; es:si -> source
  2609                                  
  2610 00000ECD 89DA                    	mov	dx,bx
  2611 00000ECF B447                    	mov	ah,47h				; save page map
  2612 00000ED1 CD67                        int 67h
  2613 00000ED3 E8920A                  	call	check_ems_error
  2614                                  
  2615 00000ED6 8B1E[A90B]              	mov	bx,WORD PTR [emsxms_offset+2]
  2616 00000EDA 033E[A70B]              	add	di,WORD PTR [emsxms_offset]
  2617 00000EDE 83D300                  	adc	bx,0
  2618 00000EE1 89F8                    	mov	ax,di				; byte offset in bx:ax
  2619 00000EE3 81E7FF3F                	and	di,3fffh			; mask to 16K page
  2620 00000EE7 D1E0                    	shl	ax,1				; convert bytes in bx:ax to page with remainder truncation
  2621 00000EE9 D1D3                    	rcl	bx,1
  2622 00000EEB D1E0                    	shl	ax,1
  2623 00000EED D1D3                    	rcl	bx,1				; bx==page number
  2624                                  
  2625 00000EEF 1E                      	push	ds				; save critical registers
  2626 00000EF0 06                      	push	es
  2627 00000EF1 8E06[8E09]              	mov	es,[D.D._ovl_ems_base]	; es:di -> destination
  2628 00000EF5 1F                      	pop	ds					; ds:si -> source
  2629                                  
  2630                                  owr_map:
  2631 00000EF6 B80044                      mov ax,4400h			; map expanded memory page to page 0
  2632 00000EF9 CD67                        int 67h
  2633 00000EFB E86A0A                  	call	check_ems_error
  2634                                  
  2635                                  ; copy to destination
  2636 00000EFE 89C8                    	mov	ax,cx
  2637 00000F00 01F8                    	add	ax,di
  2638 00000F02 3D0040                  	cmp	ax,4000h			; see if overflow to next page
  2639 00000F05 7617                    	jbe	owr_noover			; no
  2640                                  
  2641                                  ; transfer to end of page
  2642 00000F07 B80040                  	mov	ax,4000h
  2643 00000F0A 29F8                    	sub	ax,di				; get chars to transfer for this page
  2644 00000F0C 29C1                    	sub	cx,ax				; update total transferred char count
  2645 00000F0E 91                      	xchg	ax,cx			; ax==total transfer char count, cx==page transfer char count
  2646 00000F0F D1E9                        shr cx,1                ; convert byte count to write to words
  2647 00000F11 F3A5                        rep movsw               ; move the string
  2648 00000F13 D1D1                        rcl cx,1                ; pick up carry
  2649 00000F15 F3A4                        rep movsb               ; transfer leftover byte, if any
  2650 00000F17 89C1                    	mov	cx,ax				; total transfer char count back in cx
  2651                                  
  2652 00000F19 43                      	inc	bx					; move to next logical page
  2653 00000F1A 31FF                    	xor	di,di				; zero offset on next page
  2654 00000F1C EBD8                    	jmp	SHORT owr_map		; do next page transfer
  2655                                  
  2656                                  owr_noover:
  2657 00000F1E D1E9                        shr cx,1                ; convert byte count to write to words
  2658 00000F20 F3A5                        rep movsw               ; move the string
  2659 00000F22 D1D1                        rcl cx,1                ; pick up carry
  2660 00000F24 F3A4                        rep movsb               ; transfer leftover byte, if any
  2661                                  
  2662 00000F26 B448                    	mov	ah,48h				; restore page map
  2663 00000F28 CD67                        int 67h
  2664 00000F2A E83B0A                  	call	check_ems_error
  2665 00000F2D 1F                      	pop	ds					; restore critical registers
  2666 00000F2E 07                      	pop	es
  2667 00000F2F C3                      	ret
  2668                                  ovl_emsxms_write	ENDP
  2669                                  
  2670                                  ;*****************************
  2671                                  ;* $$_OVL_LOAD_OVERLAY       *
  2672                                  ;*****************************
  2673                                  
  2674                                  ; load overlay from .OVL file, performing segment fixups as necessary
  2675                                  ; destroys ax,bx,cx,dx
  2676                                  
  2677                                  D.D._ovl_load_overlay PROC    NEAR
  2678 00000F30 90                          nop                     ; trapped by profiler
  2679 00000F31 C606[8509]00            	mov byte [emsxms_stash_flag],0	; init stash flag to failure status
  2680 00000F36 06                          push    es              ; save critical register
  2681 00000F37 57                          push    di
  2682                                  
  2683 00000F38 8B3E[3601]                  mov di,[ofh_near_vector]  ; save offset to near vector
  2684                                  
  2685                                  ; maintain load/reload count for profiler
  2686 00000F3C 2E803E[3600]00              cmp byte [cs:is_calling_ovl], 0  ; load or reload?
  2687 00000F42 740C                        je load_1
  2688 00000F44 8306[EF0B]01                add word [D.D._ovl_load_count+0],1  ; increment load count
  2689 00000F49 8316[F10B]00                adc word [D.D._ovl_load_count+2],0
  2690 00000F4E EB0A                        jmp SHORT load_2
  2691                                  load_1:
  2692 00000F50 8306[F30B]01                add word [D.D._ovl_reload_count+0],1  ; increment reload count
  2693 00000F55 8316[F50B]00                adc word [D.D._ovl_reload_count+2],0
  2694                                  load_2:
  2695                                  
  2696                                  ; check if can load from overlay file stashed in EMS or XMS
  2697 00000F5A 803E[8409]00            	cmp	byte [info_from_emsxms_flag],0
  2698 00000F5F 7405                    	je	load_seek			; overlay not stashed
  2699 00000F61 E8C300                  	call	ovl_emsxms_load_ovl	; load overlay from EMS/XMS
  2700 00000F64 EB3A                    	jmp	SHORT load_fixup
  2701                                  
  2702                                  ; seek to overlay file code
  2703                                  load_seek:
  2704 00000F66 8B1E[2401]                  mov bx,[D.D._ovl_file_handle]   ; get handle of overlay file
  2705 00000F6A 833E[3801]00                cmp word [ofh_reloc_count],0   ; see if any relocation items
  2706 00000F6F 740E                        je load_3               ; no, file pointer already at overlay file code
  2707                                  
  2708 00000F71 8B16[3201]                  mov dx,[ofh_ovl_offset]   ; get offset to overlay code
  2709 00000F75 83EA0A                      sub dx,10               ; adjust for system info bytes read in
  2710 00000F78 31C9                        xor cx,cx               ; zero high word of offset
  2711 00000F7A B80142                      mov ax,4201h            ; move file pointer, relative to current file position
  2712 00000F7D CD21                        int 21h
  2713                                  
  2714                                  ; load overlay file code
  2715                                  load_3:
  2716 00000F7F 1E                          push    ds              ; save -> overlay manager data
  2717 00000F80 31D2                        xor dx,dx               ; zero load offset
  2718 00000F82 8B0E[3401]                  mov cx,[ofh_ovl_size]     ; get size of overlay in paragraphs
  2719 00000F86 D1E1                        shl cx,1                ; convert to bytes, should always be <64K
  2720 00000F88 D1E1                        shl cx,1                ; x4
  2721 00000F8A D1E1                        shl cx,1                ; x8
  2722 00000F8C D1E1                        shl cx,1                ; x16
  2723                                  
  2724                                  err_retry7:
  2725 00000F8E 8E1E[3E01]                  mov ds,[D.D._ovl_load_seg]  ; ds:dx -> read buffer
  2726                                  
  2727                                  ;***    mov ah,3fh              ; read file
  2728                                  ;***    int 21h
  2729 00000F92 E8DF09                  	call	read_to_ems
  2730                                  
  2731 00000F95 7305                        jnc load_4              ; no errors
  2732                                  
  2733 00000F97 E8FE02                      call NEAR PTR D.D._ovl_dos_error
  2734 00000F9A EBF2                        jmp SHORT err_retry7
  2735                                  
  2736                                  load_4:
  2737 00000F9C 1F                      	pop	ds					; restore ds -> overlay manager data
  2738                                  
  2739                                  ; check if can stash overlay in EMS or XMS, including header info
  2740 00000F9D E8CB00                  	call	ovl_emsxms_stash_ovl
  2741                                  
  2742                                  ; perform segment fixups on overlay vectors
  2743                                  load_fixup:
  2744 00000FA0 1E                      	push	ds				; save -> overlay manager data
  2745 00000FA1 8E1E[3E01]                  mov ds,[D.D._ovl_load_seg]  ; ds:dx -> read buffer, KEEP FLAG STATUS
  2746                                  D.D._ovl_code equ D.D._OVL_CODE	; NASM port equate
  2747 00000FA5 B8[ssss]                    mov ax,D.D._ovl_code      ; get current segment of overlay manager code
  2748 00000FA8 89450D                      mov [di+0dh],ax      ; fixup near vector
  2749 00000FAB 89451A                      mov [di+1ah],ax      ; fixup shared vector
  2750 00000FAE 1F                          pop ds                  ; restore ds -> overlay manager data
  2751                                  
  2752                                  ; seek to start of relocation table if any relocation items
  2753 00000FAF 833E[3801]00                cmp word [ofh_reloc_count],0   ; see if any relocation items
  2754 00000FB4 7439                        je load_ret             ; no
  2755                                  
  2756 00000FB6 8B16[1E01]                  mov dx,WORD PTR [D.D._ovl_file_offset]  ; get low word of overlay file offset
  2757 00000FBA 8B0E[2001]                  mov cx,WORD PTR [D.D._ovl_file_offset+2]    ; get high word of overlay file offset
  2758 00000FBE 83C20A                      add dx,10               ; adjust past system info bytes to start of relocation entries
  2759 00000FC1 83D100                      adc cx,0
  2760                                  
  2761                                  ; bypass file seek if loading from EMS or XMS, but update $$_ovl_file_offset
  2762 00000FC4 803E[8409]00            	cmp	byte [info_from_emsxms_flag],0
  2763 00000FC9 740A                    	je	load_seek2			; overlay not stashed
  2764 00000FCB 8916[1E01]                  mov WORD PTR [D.D._ovl_file_offset],dx  ; update overlay file offset
  2765 00000FCF 890E[2001]                  mov WORD PTR [D.D._ovl_file_offset+2],cx
  2766 00000FD3 EB0B                    	jmp	SHORT load_loop
  2767                                  
  2768                                  load_seek2:
  2769 00000FD5 B80042                      mov ax,4200h            ; move file pointer, relative beginning of file
  2770 00000FD8 CD21                        int 21h
  2771 00000FDA C706[1E01]0A00          	mov	WORD [D.D._ovl_file_offset],10	; init low word overlay file offset to reloc entries in case of stashing
  2772                                  
  2773                                  ; load and fixup relocation items, if any.  Reload as necessary
  2774                                  load_loop:
  2775 00000FE0 833E[3801]00                cmp word [ofh_reloc_count],0   ; see if any more relocation items
  2776 00000FE5 7408                        je load_ret             ; nope, done
  2777 00000FE7 E81B01                      call    D.D._ovl_load_reloc   ; load relocation entries (up to 512)
  2778 00000FEA E88401                      call    D.D._ovl_fixup    ; perform relocation fixups
  2779 00000FED EBF1                        jmp SHORT load_loop     ; loop back for more
  2780                                  
  2781                                  load_ret:
  2782 00000FEF 803E[8509]00            	cmp	byte [emsxms_stash_flag],0	; see if stashing current overlay
  2783 00000FF4 742E                    	je	load_out			; no
  2784                                  
  2785                                  ; update free EMS/XMS space
  2786 00000FF6 A1[3201]                	mov	ax,[ofh_ovl_offset]	; subtract off overlay file header size
  2787 00000FF9 2906[A30B]              	sub	WORD PTR [emsxms_free],ax
  2788 00000FFD 831E[A50B]00            	sbb	WORD [emsxms_free+2],0
  2789 00001002 0106[A70B]              	add	WORD PTR [emsxms_offset],ax	; update stash offset
  2790 00001006 8316[A90B]00            	adc	WORD [emsxms_offset+2],0
  2791 0000100B A1[3401]                	mov	ax,[ofh_ovl_size]
  2792 0000100E B104                    	mov	cl,4
  2793 00001010 D3E0                    	shl	ax,cl				; convert overlay size in paras to bytes
  2794 00001012 2906[A30B]              	sub	WORD PTR [emsxms_free],ax	; subtract off overlay size
  2795 00001016 831E[A50B]00            	sbb	WORD [emsxms_free+2],0
  2796 0000101B 0106[A70B]              	add	WORD PTR [emsxms_offset],ax	; update stash offset
  2797 0000101F 8316[A90B]00            	adc	WORD [emsxms_offset+2],0
  2798                                  
  2799                                  load_out:
  2800 00001024 5F                          pop di					; restore critical register
  2801 00001025 07                          pop es
  2802 00001026 C3                          ret
  2803                                  D.D._ovl_load_overlay ENDP
  2804                                  
  2805                                  ;*****************************
  2806                                  ;* OVL_EMSXMS_LOAD_OVL       *
  2807                                  ;*****************************
  2808                                  
  2809                                  ; load from overlay file stashed in EMS or XMS
  2810                                  ; destroys ax,bx,cx,dx
  2811                                  
  2812                                  ovl_emsxms_load_ovl	PROC	NEAR
  2813 00001027 56                      	push	si				; save critical register
  2814 00001028 57                      	push	di
  2815                                  
  2816 00001029 31FF                    	xor	di,di				; zero offset within load area
  2817 0000102B 8B0E[3401]                  mov cx,[ofh_ovl_size]     ; get size of overlay in paragraphs
  2818 0000102F D1E1                        shl cx,1                ; convert to bytes, should always be <64K
  2819 00001031 D1E1                        shl cx,1				; x4
  2820 00001033 D1E1                        shl cx,1				; x8
  2821 00001035 D1E1                        shl cx,1				; x16
  2822 00001037 8B36[1E01]              	mov	si,WORD PTR [D.D._ovl_file_offset]	; source offset
  2823 0000103B 8B1E[2001]              	mov	bx,WORD PTR [D.D._ovl_file_offset+2]	; logical page number/high word source offset
  2824 0000103F 80E73F                  	and	bh,3fh				; mask off EMS/XMS flag bits
  2825                                  
  2826 00001042 F606[8409]80            	test	byte [info_from_emsxms_flag],80h	; see if XMS flag set
  2827 00001047 7511                    	jne	oel_xms				; yes
  2828                                  
  2829                                  ; EMS, when adjusting source offset must check if flowing into next page
  2830 00001049 0336[3201]              	add	si,[ofh_ovl_offset]	; si -> code after header info
  2831 0000104D 81FE0040                	cmp	si,4000h			; see if into next page
  2832 00001051 720E                    	jb	oel_readin			; no
  2833 00001053 43                      	inc	bx					; bump page count
  2834 00001054 81E6FF3F                	and	si,3fffh			; mask to page
  2835 00001058 EB07                    	jmp	SHORT oel_readin
  2836                                  
  2837                                  ; XMS, adjust source offset in si,bl
  2838                                  oel_xms:
  2839 0000105A 0336[3201]              	add	si,[ofh_ovl_offset]	; si -> code after header info
  2840 0000105E 80D300                  	adc	bl,0				; carry to high byte
  2841                                  
  2842                                  ; bx==logical page number (EMS)/high byte source offset (XMS)
  2843                                  ; cx==count of chars to transfer
  2844                                  ; si==source offset
  2845                                  ; di==destination offset
  2846                                  oel_readin:
  2847 00001061 8B16[3E01]                  mov dx,[D.D._ovl_load_seg]  ; dx==destination segment
  2848 00001065 E8F1FC                  	call	ovl_emsxms_read	; read in the info from EMS/XMS
  2849 00001068 5F                      	pop	di					; restore critical register
  2850 00001069 5E                      	pop	si
  2851 0000106A C3                      	ret
  2852                                  ovl_emsxms_load_ovl	ENDP
  2853                                  
  2854                                  ;*****************************
  2855                                  ;* OVL_EMSXMS_STASH_OVL      *
  2856                                  ;*****************************
  2857                                  
  2858                                  ; check if can stash overlay in EMS or XMS, including header info
  2859                                  ;   update file offset table if so
  2860                                  ; upon entry jump_segment variable holds overlay identifier,
  2861                                  ; destroys ax,cx,dx
  2862                                  
  2863                                  ovl_emsxms_stash_ovl	PROC	NEAR
  2864 0000106B A0[7E09]                	mov	al,[D.D._ovl_ohp]
  2865 0000106E 0A06[7F09]              	or	al,[D.D._ovl_oht]		; see if stashing was indicated
  2866 00001072 741E                    	je	oes_fail			; no
  2867                                  
  2868                                  ; check if EMS/XMS free is >= size of stash
  2869 00001074 A1[3401]                	mov	ax,[ofh_ovl_size]
  2870 00001077 B104                    	mov	cl,4
  2871 00001079 D3E0                    	shl	ax,cl				; convert overlay size in paras to bytes
  2872 0000107B 31C9                    	xor	cx,cx
  2873 0000107D 0306[3201]              	add	ax,[ofh_ovl_offset]	; add in overlay file header size
  2874 00001081 83D100                  	adc	cx,0				; carry to high word, total size in cx:ax
  2875 00001084 3B0E[A50B]              	cmp	cx,WORD PTR [emsxms_free+2]
  2876 00001088 7708                    	ja	oes_fail			; not enough room
  2877 0000108A 7207                    	jb	oes_okay			; enough room
  2878                                  
  2879                                  ; high words match, check low
  2880 0000108C 3B06[A30B]              	cmp	ax,WORD PTR [emsxms_free]
  2881 00001090 7601                    	jbe	oes_okay			; enough room
  2882                                  
  2883                                  ; not enough room to stash this overlay
  2884                                  oes_fail:
  2885 00001092 C3                      	ret						; return with stash flag reset
  2886                                  
  2887                                  oes_okay:
  2888 00001093 53                      	push	bx				; save critical register
  2889 00001094 56                      	push	si
  2890 00001095 57                      	push	di
  2891 00001096 B90A00                  	mov	cx,10				; overlay system header size
  2892 00001099 BE[3001]                    mov si,OFFSET D.D._ovl_file_header
  2893 0000109C 31FF                    	xor	di,di
  2894 0000109E 8CDA                    	mov	dx,ds
  2895                                  
  2896                                  ; write header info to stash
  2897                                  ; cx==count of chars to transfer
  2898                                  ; di==destination offset relative to emsxms_offset start position
  2899                                  ; si==source offset
  2900                                  ; dx==source segment
  2901 000010A0 E885FD                  	call	ovl_emsxms_write	; write info to EMS/XMS
  2902                                  
  2903                                  ; write overlay code to stash
  2904 000010A3 8B3E[3201]              	mov	di,[ofh_ovl_offset]
  2905 000010A7 8B0E[3401]                  mov cx,[ofh_ovl_size]     ; get size of overlay in paragraphs
  2906 000010AB D1E1                        shl cx,1                ; convert to bytes, should always be <64K
  2907 000010AD D1E1                        shl cx,1				; x4
  2908 000010AF D1E1                        shl cx,1				; x8
  2909 000010B1 D1E1                        shl cx,1				; x16
  2910 000010B3 8B16[3E01]                  mov dx,[D.D._ovl_load_seg]  ; overlay load (source) segment
  2911 000010B7 31F6                    	xor	si,si				; zero offset within overlay load area
  2912 000010B9 E86CFD                  	call	ovl_emsxms_write	; write info to EMS/XMS
  2913                                  
  2914                                  ; calculate page/offset (EMS) or offset (XMS) in dx:bx to update file position table
  2915 000010BC 803E[7F09]00            	cmp	byte [D.D._ovl_oht],0		; see if XMS stashing
  2916 000010C1 740C                    	je	oes_ems				; no
  2917 000010C3 8B1E[A70B]              	mov	bx,WORD PTR [emsxms_offset]
  2918 000010C7 8B16[A90B]              	mov	dx,WORD PTR [emsxms_offset+2]
  2919 000010CB B080                    	mov	al,80h				; XMS stash flag
  2920 000010CD EB17                    	jmp	SHORT oes_update
  2921                                  
  2922                                  oes_ems:
  2923 000010CF 8B1E[A70B]              	mov	bx,WORD PTR [emsxms_offset]
  2924 000010D3 89D9                    	mov	cx,bx
  2925 000010D5 80E73F                  	and	bh,3fh				; mask to 16K page
  2926 000010D8 8B16[A90B]              	mov	dx,WORD PTR [emsxms_offset+2]
  2927 000010DC D1E1                    	shl	cx,1
  2928 000010DE D1D2                    	rcl	dx,1
  2929 000010E0 D1E1                    	shl	cx,1
  2930 000010E2 D1D2                    	rcl	dx,1				; dx==page number
  2931 000010E4 B040                    	mov	al,40h				; EMS stash flag
  2932                                  
  2933                                  oes_update:
  2934 000010E6 08C6                    	or	dh,al				; set stash flags
  2935 000010E8 0806[8509]              	or	[emsxms_stash_flag],al	; set stash flag to indicate successful stash
  2936                                  
  2937 000010EC 1E                      	push	ds				; save -> overlay manager data
  2938 000010ED 2E8B36[2600]                mov si,[cs:jump_segment]	; get overlay identifier
  2939 000010F2 4E                          dec si					; make relative zero
  2940 000010F3 D1E6                        shl si,1				; make doubleword offset into file position table
  2941 000010F5 D1E6                        shl si,1
  2942 000010F7 8E1E[0A01]                  mov ds,[D.D._ovl_filepos]	; ds -> overlay file position table
  2943 000010FB 891C                        mov [si],bx				; save new file position
  2944 000010FD 895402                      mov [si+2],dx
  2945 00001100 1F                      	pop	ds					; restore ds -> overlay manager data
  2946                                  
  2947 00001101 5F                      	pop	di					; restore critical register
  2948 00001102 5E                      	pop	si
  2949 00001103 5B                      	pop	bx
  2950                                  
  2951 00001104 C3                      	ret
  2952                                  ovl_emsxms_stash_ovl	ENDP
  2953                                  
  2954                                  ;*****************************
  2955                                  ;* $$_OVL_LOAD_RELOC         *
  2956                                  ;*****************************
  2957                                  
  2958                                  ; load relocation table, if any
  2959                                  ; update relocation items count
  2960                                  ; destroys ax,bx,cx,dx
  2961                                  
  2962                                  D.D._ovl_load_reloc   PROC    NEAR
  2963                                  
  2964                                  err_retry8:
  2965 00001105 8B1E[2401]                  mov bx,[D.D._ovl_file_handle]   ; get handle of overlay file
  2966 00001109 BA[5B01]                    mov dx,OFFSET D.D._ovl_rel_table  ; ds:dx -> place to load table
  2967 0000110C 8B0E[3801]                  mov cx,[ofh_reloc_count]  ; get count of relocation items
  2968 00001110 D1E1                        shl cx,1                ; cx holds byte count of items (2 bytes/item)
  2969 00001112 81F90004                    cmp cx,1024             ; see if table would overflow
  2970 00001116 7603                        jbe reloc_2             ; no
  2971 00001118 B90004                      mov cx,1024             ; set to maximum
  2972                                  
  2973                                  ; if loading from overlay file in EMS or XMS, get relocation entries
  2974                                  reloc_2:
  2975 0000111B 803E[8409]00            	cmp	byte [info_from_emsxms_flag],0
  2976 00001120 7404                    	je	reloc_read			; overlay not stashed
  2977 00001122 E81000                  	call	ovl_emsxms_load_reloc
  2978 00001125 C3                      	ret
  2979                                  
  2980                                  reloc_read:
  2981 00001126 B43F                        mov ah,3fh              ; read file
  2982 00001128 CD21                        int 21h
  2983 0000112A 7305                        jnc reloc_ret           ; no errors
  2984                                  
  2985 0000112C E86901                      call NEAR PTR D.D._ovl_dos_error
  2986 0000112F EBD4                        jmp SHORT err_retry8
  2987                                  
  2988                                  ; if stashing overlay file to EMS or XMS, write relocation entries
  2989                                  reloc_ret:
  2990 00001131 E82100                  	call	ovl_emsxms_stash_reloc
  2991 00001134 C3                          ret
  2992                                  D.D._ovl_load_reloc   ENDP
  2993                                  
  2994                                  ;*****************************
  2995                                  ;* OVL_EMSXMS_LOAD_RELOC     *
  2996                                  ;*****************************
  2997                                  
  2998                                  ; get relocation entries from stashed overlay in EMS/XMS
  2999                                  ; update $$_ovl_file_offset with bytes read in
  3000                                  ; upon entry cx==bytes to read, ds:dx -> destination area
  3001                                  ; destroys ax,bx,cx,dx
  3002                                  
  3003                                  ovl_emsxms_load_reloc	PROC	NEAR
  3004 00001135 56                      	push	si				; save critical register
  3005 00001136 57                      	push	di
  3006 00001137 89D7                    	mov	di,dx
  3007 00001139 8B36[1E01]              	mov	si,WORD PTR [D.D._ovl_file_offset]	; source offset
  3008 0000113D 8B1E[2001]              	mov	bx,WORD PTR [D.D._ovl_file_offset+2]	; logical page number/high word source offset
  3009 00001141 80E73F                  	and	bh,3fh				; mask off EMS/XMS flag bits
  3010 00001144 8CDA                    	mov	dx,ds
  3011                                  
  3012                                  ; update file offset for next load
  3013 00001146 010E[1E01]              	add	WORD PTR [D.D._ovl_file_offset],cx
  3014 0000114A 8316[2001]00            	adc	WORD [D.D._ovl_file_offset+2],0
  3015                                  
  3016                                  ; bx==logical page number (EMS)/high byte source offset (XMS)
  3017                                  ; cx==count of chars to transfer
  3018                                  ; dx==destination segment
  3019                                  ; si==source offset
  3020                                  ; di==destination offset
  3021 0000114F E807FC                  	call	ovl_emsxms_read	; read in the info from EMS/XMS
  3022 00001152 5F                      	pop	di					; restore critical register
  3023 00001153 5E                      	pop	si
  3024 00001154 C3                      	ret
  3025                                  ovl_emsxms_load_reloc	ENDP
  3026                                  
  3027                                  ;*****************************
  3028                                  ;* OVL_EMSXMS_STASH_RELOC    *
  3029                                  ;*****************************
  3030                                  
  3031                                  ; stash relocation entries from overlay in EMS/XMS if appropriate
  3032                                  ; upon entry cx==bytes to stash, ds:dx -> source
  3033                                  ; destroys ax,bx,cx,dx
  3034                                  
  3035                                  ovl_emsxms_stash_reloc	PROC	NEAR
  3036 00001155 803E[8509]00            	cmp	byte [emsxms_stash_flag],0	; see if stashing current overlay
  3037 0000115A 7501                    	jne	oer_stash			; yes
  3038 0000115C C3                      	ret						; no
  3039                                  
  3040                                  oer_stash:
  3041 0000115D 56                      	push	si				; save critical register
  3042 0000115E 57                      	push	di
  3043 0000115F 89D6                    	mov	si,dx
  3044 00001161 8CDA                    	mov	dx,ds
  3045 00001163 8B3E[1E01]              	mov	di,WORD PTR [D.D._ovl_file_offset]	; running offset of relocation entries
  3046                                  
  3047                                  ; update relocation entry file offset for next stash
  3048 00001167 010E[1E01]              	add	WORD PTR [D.D._ovl_file_offset],cx
  3049                                  
  3050                                  ; cx==count of chars to transfer
  3051                                  ; di==destination offset relative to emsxms_offset start position
  3052                                  ; si==source offset
  3053                                  ; dx==source segment
  3054 0000116B E8BAFC                  	call	ovl_emsxms_write	; write info to EMS/XMS
  3055 0000116E 5F                      	pop	di					; restore critical register
  3056 0000116F 5E                      	pop	si
  3057 00001170 C3                      	ret
  3058                                  ovl_emsxms_stash_reloc	ENDP
  3059                                  
  3060                                  ;*****************************
  3061                                  ;* $$_OVL_FIXUP              *
  3062                                  ;*****************************
  3063                                  
  3064                                  ; perform relocation entry segment fixups for overlay file
  3065                                  ; destroys ax,bx,cx,dx,es
  3066                                  
  3067                                  D.D._ovl_fixup    PROC    NEAR
  3068 00001171 56                          push    si              ; save critical register
  3069 00001172 57                          push    di
  3070 00001173 A1[3801]                    mov ax,[ofh_reloc_count]  ; get count of relocation items
  3071 00001176 89C1                        mov cx,ax
  3072 00001178 3D0002                      cmp ax,512              ; check if at least 512 items (full table)
  3073 0000117B 7305                        jae fixup_2             ; yes
  3074 0000117D B80002                      mov ax,512              ; force ax to minimum value for update by subtraction
  3075 00001180 EB03                        jmp SHORT fixup_3
  3076                                  
  3077                                  fixup_2:
  3078 00001182 B90002                      mov cx,512              ; don't perform more than 512 fixups at once
  3079                                  
  3080                                  fixup_3:
  3081 00001185 2D0002                      sub ax,512              ; back off count of items fixed-up this pass (512 or all)
  3082 00001188 A3[3801]                    mov [ofh_reloc_count],ax  ; update count of fixup items
  3083 0000118B 8B16[3E01]                  mov dx,[D.D._ovl_load_seg]
  3084 0000118F 8EC2                        mov es,dx               ; es -> overlay file code
  3085 00001191 BB[5B01]                    mov bx,OFFSET D.D._ovl_rel_table  ; ds:bx -> relocation table
  3086                                  
  3087                                  fixup_loop:
  3088 00001194 8B37                        mov si,[bx]             ; es:si -> overlay location to fixup
  3089 00001196 09F6                        or  si,si               ; see if zero (due to fixup of absolute segment being counted)
  3090 00001198 7416                        je  fixup_5             ; yes, don't fixup value
  3091 0000119A 268B04                      mov ax,[es:si]          ; get original value
  3092                                  
  3093                                  ; see if original value is nonzero.
  3094                                  ; if so, assume root relative fixup
  3095 0000119D 09C0                        or  ax,ax
  3096 0000119F 740A                        je  fixup_ovl           ; zero, overlay segment relative
  3097                                  
  3098                                  ; root relative fixup
  3099 000011A1 2E0306[2A00]                add ax,[cs:prog_psp]      ; add in program's psp segment
  3100 000011A6 83C010                      add ax,10h              ; adjust for psp segment
  3101 000011A9 EB02                        jmp SHORT fixup_4       ; bypass overlay segment relative fixup
  3102                                  
  3103                                  fixup_ovl:
  3104 000011AB 89D0                        mov ax,dx               ; use overlay load segment as fixup
  3105                                  
  3106                                  fixup_4:
  3107 000011AD 268904                      mov [es:si],ax          ; update value
  3108                                  
  3109                                  fixup_5:
  3110 000011B0 83C302                      add bx,2                ; move to next relocation item
  3111 000011B3 E2DF                        loop    fixup_loop      ; loop until complete
  3112                                  
  3113 000011B5 5F                          pop di                  ; restore critical register
  3114 000011B6 5E                          pop si
  3115 000011B7 C3                          ret
  3116                                  D.D._ovl_fixup    ENDP
  3117                                  
  3118                                  ;*****************************
  3119                                  ;* $$_OVL_SWAP_IN            *
  3120                                  ;*****************************
  3121                                  
  3122                                  ; swap in all all active overlays swapped out by terminated overlay
  3123                                  ; upon entry ds -> overlay manager data
  3124                                  ; destroys ax,bx,cx
  3125                                  
  3126                                  D.D._ovl_swap_in  PROC    NEAR
  3127 000011B8 06                          push    es              ; save critical register
  3128 000011B9 52                          push    dx
  3129                                  
  3130                                  ; set stack to calling routine seg/id/offset stack
  3131                                  swap_loop:
  3132 000011BA 2E8926[0800]                mov [cs:D.D._ovl_mgr_stack_ptr],sp  ; first save current stack pointer
  3133 000011BF 2E8B1E[0400]                mov bx,[cs:D.D._ovl_stack_ptr]
  3134 000011C4 2EA1[0600]                  mov ax,[cs:D.D._ovl_stack_start]
  3135 000011C8 FA                          cli                     ; shut off interrupts while stack is set
  3136 000011C9 8ED0                        mov ss,ax
  3137 000011CB 89DC                        mov sp,bx               ; set internal stack
  3138 000011CD FB                          sti                     ; turn interrupts back on
  3139                                  
  3140 000011CE 8F06[4E01]                  pop word [D.D._ovl_activity]     ; get activity level
  3141 000011D2 8F06[5001]                  pop word [swapped_lru_high]    ; get swapped out overlay LRU high word
  3142 000011D6 8F06[5201]                  pop word [swapped_lru_low]     ; get swapped out overlay LRU low word
  3143 000011DA 2E8F06[2600]                pop word [cs:jump_segment]     ; get overlay identifier in jump_segment variable
  3144 000011DF 8F06[3E01]                  pop word [D.D._ovl_load_seg]     ; get overlay load segment
  3145 000011E3 2E8926[0400]                mov [cs:D.D._ovl_stack_ptr],sp  ; save new stack pointer value
  3146                                  
  3147                                  ; set stack to overlay manager internal stack
  3148 000011E8 2E8B1E[0800]                mov bx,[cs:D.D._ovl_mgr_stack_ptr]
  3149 000011ED B8[ssss]                    mov ax,SEG D.D._ovl_mgr_stack_end
  3150 000011F0 FA                          cli                     ; shut off interrupts while stack is set
  3151 000011F1 8ED0                        mov ss,ax
  3152 000011F3 89DC                        mov sp,bx               ; set internal stack
  3153 000011F5 FB                          sti                     ; turn interrupts back on
  3154                                  
  3155 000011F6 E87A06                      call    xmsems_swapin   ; try to swap in from active overlay stash area, if there
  3156 000011F9 08C0                        or  al,al               ; see if success
  3157 000011FB 7506                        jne swap_loaded         ; yes
  3158                                  
  3159 000011FD E8E9FA                      call    D.D._ovl_get_info     ; get overlay information
  3160 00001200 E82DFD                      call    D.D._ovl_load_overlay ; load the overlay
  3161                                  
  3162                                  swap_loaded:
  3163 00001203 8E06[0401]                  mov es,[D.D._ovl_array_start]   ; es-> array element for new overlay
  3164                                  
  3165                                  swap_loop2:
  3166 00001207 26A10000                    mov ax,[es:0]
  3167 0000120B 09C0                        or  ax,ax               ; see if array element used
  3168 0000120D 7407                        je  swap_3              ; no, use it
  3169 0000120F 8CC0                        mov ax,es
  3170 00001211 40                          inc ax
  3171 00001212 8EC0                        mov es,ax               ; bump to next array element
  3172 00001214 EBF1                        jmp SHORT swap_loop2    ; loop until unused array element found
  3173                                  
  3174                                  swap_3:
  3175 00001216 06                          push    es              ; save -> unused array element
  3176 00001217 8B16[3E01]                  mov dx,[D.D._ovl_load_seg]  ; ax holds start paragraph
  3177 0000121B 89D3                        mov bx,dx
  3178 0000121D 031E[3401]                  add bx,[ofh_ovl_size]     ; add in size of overlay in paragraphs to get end paragraph
  3179                                  
  3180                                  ; check if swapped in overlay overwrites any nonactive overlays
  3181 00001221 A1[0401]                    mov ax,[D.D._ovl_array_start]
  3182 00001224 8EC0                        mov es,ax               ; es -> overlay array
  3183 00001226 8B0E[2201]                  mov cx,[D.D._ovl_loaded_count]  ; get count of loaded overlays to check
  3184                                  
  3185                                  swap_zero_loop:
  3186 0000122A E333                        jcxz    swap_4          ; no more overlays to check
  3187 0000122C 26A10000                    mov ax,[es:0]           ; get overlay identifier number
  3188 00001230 09C0                        or  ax,ax               ; check overlay id
  3189 00001232 7424                        je  swap_next           ; zero id number
  3190                                  
  3191 00001234 49                          dec cx                  ; drop count of overlays to check
  3192 00001235 2E3B06[2600]                cmp ax,[cs:jump_segment]  ; see if swapped-in overlay matches previous overlay
  3193 0000123A 740E                        je SHORT do_swap        ; yes, zero out previous overlay entry and activate this one
  3194                                  
  3195                                  swap_cont:
  3196 0000123C 263B160800                  cmp dx,[es:8]           ; check swap-in start against entry overlay end
  3197 00001241 7315                        jae swap_next           ; above end, overlay not swapped
  3198 00001243 263B1E0600                  cmp bx,[es:6]           ; check swap-in end against entry overlay start
  3199 00001248 760E                        jbe swap_next           ; below start, overlay not swapped
  3200                                  
  3201                                  do_swap:
  3202 0000124A 31C0                        xor ax,ax
  3203 0000124C 26A30000                    mov [es:0],ax           ; zero overlay identifier for this array element
  3204 00001250 26A30400                    mov [es:4],ax           ; zero activity level
  3205 00001254 FF0E[2201]                  dec word [D.D._ovl_loaded_count] ; drop count of loaded overlays
  3206                                  
  3207                                  swap_next:
  3208 00001258 8CC0                        mov ax,es               ; get array element segment
  3209 0000125A 40                          inc ax                  ; bump to next element
  3210 0000125B 8EC0                        mov es,ax               ; update array element pointer
  3211 0000125D EBCB                        jmp SHORT swap_zero_loop    ; loop back until all loaded overlays checked
  3212                                  
  3213                                  ; all non-active overlays overwritten by swapped-in overlay have their entries zeroed
  3214                                  ; update swapped-in, active overlay entry data
  3215                                  swap_4:
  3216 0000125F 07                          pop es                  ; es -> unused array element
  3217 00001260 2689160600                  mov [es:6],dx           ; save start paragraph
  3218 00001265 26891E0800                  mov [es:8],bx           ; save end paragraph
  3219                                  
  3220 0000126A 2EA1[2600]                  mov ax,[cs:jump_segment]
  3221 0000126E 26A30000                    mov [es:0],ax           ; save overlay identifier
  3222                                  
  3223 00001272 A1[4E01]                    mov ax,[D.D._ovl_activity]
  3224 00001275 26A30400                    mov [es:4],ax           ; save activity level
  3225                                  
  3226                                  ; set LRU counter to what it was before swapout
  3227 00001279 A1[5201]                    mov ax,[swapped_lru_low]
  3228 0000127C 26A30A00                    mov [es:10],ax
  3229 00001280 A1[5001]                    mov ax,[swapped_lru_high]
  3230 00001283 26A30C00                    mov [es:12],ax
  3231 00001287 FF06[2201]                  inc word [D.D._ovl_loaded_count]     ; increment count of loaded overlays
  3232                                  
  3233                                  swap_decstack:
  3234 0000128B 2EFF0E[3200]                dec word [cs:D.D._ovl_stackcount]    ; drop count of loaded overlays on stack
  3235 00001290 7403                        je  swap_ret            ; done
  3236 00001292 E925FF                      jmp NEAR PTR swap_loop  ; more loaded overlays on stack
  3237                                  
  3238                                  swap_ret:
  3239 00001295 5A                          pop dx                  ; restore critical register
  3240 00001296 07                          pop es
  3241 00001297 C3                          ret
  3242                                  D.D._ovl_swap_in  ENDP
  3243                                  
  3244                                  ;*****************************
  3245                                  ;* $$_OVL_DOS_ERROR          *
  3246                                  ;*****************************
  3247                                  
  3248                                  ; DOS error occurred in overlay manager
  3249                                  ; error code in ax
  3250                                  ; if installed error handler, destroy ax,cx,bx,dx
  3251                                  ; otherwise, trash registers as necessary, this procedure terminates to DOS
  3252                                  
  3253                                  D.D._ovl_dos_error    PROC    NEAR
  3254 00001298 1E                          push    ds              ; save critical register
  3255 00001299 BA[ssss]                    mov dx,SEG _ovlmgr_error_vector
  3256 0000129C 8EDA                        mov ds,dx               ; ds -> error handler data segment
  3257 0000129E 8B16[0000]                  mov dx,WORD PTR [_ovlmgr_error_vector]
  3258 000012A2 8B0E[0200]                  mov cx,WORD PTR [_ovlmgr_error_vector+2]
  3259 000012A6 09CA                        or  dx,cx               ; see if installed error handler
  3260 000012A8 7433                        je  doserr2             ; no, address is zero
  3261 000012AA 2E3B0E[2A00]            	cmp	cx,[cs:prog_psp]		; additional check for valid error handler
  3262 000012AF 762C                    	jbe	doserr2				; invalid
  3263                                  
  3264                                  ; installed error handler
  3265 000012B1 8CD1                        mov cx,ss
  3266 000012B3 89E2                        mov dx,sp
  3267 000012B5 2E870E[0200]                xchg    cx,[cs:prog_ss_store] ; save overlay manager ss, get program ss in cx
  3268 000012BA 2E8716[0000]                xchg    dx,[cs:prog_sp_store] ; save overlay manager sp, get program sp in dx
  3269 000012BF 8ED1                        mov ss,cx
  3270 000012C1 89D4                        mov sp,dx               ; restore program stack values
  3271 000012C3 50                          push    ax
  3272 000012C4 FF1E[0000]                  call    far [_ovlmgr_error_vector]  ; call error handler
  3273 000012C8 58                          pop ax
  3274 000012C9 8CD1                        mov cx,ss
  3275 000012CB 89E2                        mov dx,sp
  3276 000012CD 2E870E[0200]                xchg    cx,[cs:prog_ss_store] ; save program ss, get overlay manager ss in cx
  3277 000012D2 2E8716[0000]                xchg    dx,[cs:prog_sp_store] ; save program sp, get overlay manager sp in dx
  3278 000012D7 8ED1                        mov ss,cx
  3279 000012D9 89D4                        mov sp,dx               ; restore overlay manager stack values
  3280 000012DB 1F                          pop ds                  ; restore critical register
  3281 000012DC C3                          ret                     ; return and try again
  3282                                  
  3283                                  doserr2:
  3284 000012DD BA[0000]                    mov dx,OFFSET dos_err_text  ; ds:dx -> message to write
  3285 000012E0 B91800                      mov cx,24
  3286                                  
  3287                                  D.D._ovl_err_shared:
  3288 000012E3 89C6                        mov si,ax               ; save error code
  3289 000012E5 B8[ssss]                    mov ax,D.D._ovl_data
  3290 000012E8 8ED8                        mov ds,ax               ; ds -> overlay manager data
  3291 000012EA BB0100                      mov bx,STDOUT           ; write error message to standard output
  3292 000012ED B440                        mov ah,40h              ; write to device
  3293 000012EF CD21                        int 21h
  3294                                  
  3295 000012F1 89F0                        mov ax,si               ; restore error code to ax
  3296 000012F3 88C4                        mov ah,al
  3297 000012F5 80E40F                      and ah,15               ; only save low nybble of error code
  3298 000012F8 D0E8                        shr al,1                ; convert high nybble of error code to relative zero
  3299 000012FA D0E8                        shr al,1
  3300 000012FC D0E8                        shr al,1
  3301 000012FE D0E8                        shr al,1
  3302                                  
  3303                                  ; low 4 bits of value in ah, high 4 bits in al
  3304 00001300 3C09                        cmp al,9                ; see if need to convert high nybble to hex code
  3305 00001302 7602                        jbe shared_2            ; no
  3306 00001304 0407                        add al,7                ; adjust for alpha hex char
  3307                                  
  3308                                  shared_2:
  3309 00001306 0430                        add al,30h              ; make ASCII representation
  3310 00001308 80FC09                      cmp ah,9                ; see if need to convert low nybble to hex code
  3311 0000130B 7603                        jbe shared_3            ; no
  3312 0000130D 80C407                      add ah,7                ; adjust for alpha hex char
  3313                                  
  3314                                  shared_3:
  3315 00001310 80C430                      add ah,30h              ; make ASCII representation
  3316 00001313 BF[3C00]                    mov di,OFFSET code_text ; point to code to modify
  3317 00001316 8905                        mov [di],ax             ; modify '00' code to actual value in hex
  3318                                  
  3319 00001318 89FA                        mov dx,di               ; ds:dx -> message to print
  3320 0000131A B90500                      mov cx,5                ; print 5 chars
  3321 0000131D B440                        mov ah,40h              ; write to device
  3322 0000131F CD21                        int 21h
  3323                                  
  3324 00001321 89F0                        mov ax,si               ; get low byte of error code in al
  3325 00001323 B44C                        mov ah,4ch              ; terminate with return code
  3326 00001325 CD21                        int 21h
  3327                                  D.D._ovl_dos_error    ENDP
  3328                                  
  3329                                  ;*****************************
  3330                                  ;* $$_OVL_OP_ERROR           *
  3331                                  ;*****************************
  3332                                  
  3333                                  ; Operation error occurred in overlay manager
  3334                                  ; error code in ax
  3335                                  ; trash registers as necessary, this procedure terminates to DOS or error handler
  3336                                  
  3337                                  D.D._ovl_op_error     PROC    NEAR
  3338 00001327 BA[ssss]                    mov dx,SEG _ovlmgr_error_vector
  3339 0000132A 8EDA                        mov ds,dx               ; ds -> error handler data segment
  3340 0000132C 8B16[0000]                  mov dx,WORD PTR [_ovlmgr_error_vector]
  3341 00001330 8B0E[0200]                  mov cx,WORD PTR [_ovlmgr_error_vector+2]
  3342 00001334 09CA                        or  dx,cx               ; see if installed error handler
  3343 00001336 7421                        je  operr2              ; no, address is zero
  3344 00001338 2E3B0E[2A00]            	cmp	cx,[cs:prog_psp]		; additional check for valid error handler
  3345 0000133D 761A                    	jbe	operr2				; invalid
  3346                                  
  3347                                  ; installed error handler
  3348 0000133F 80CC80                      or  ah,80h              ; set high bit to indicate overlay manager error
  3349 00001342 8CD1                        mov cx,ss
  3350 00001344 89E2                        mov dx,sp
  3351 00001346 2E870E[0200]                xchg    cx,[cs:prog_ss_store] ; save overlay manager ss, get program ss in cx
  3352 0000134B 2E8716[0000]                xchg    dx,[cs:prog_sp_store] ; save overlay manager sp, get program sp in dx
  3353 00001350 8ED1                        mov ss,cx
  3354 00001352 89D4                        mov sp,dx               ; restore program stack values
  3355 00001354 50                          push    ax
  3356 00001355 FF1E[0000]                  call    far [_ovlmgr_error_vector]  ; call error handler
  3357                                  
  3358                                  ; if they are fool enough to return, drop through to regular handler
  3359                                  
  3360                                  operr2:
  3361 00001359 BA[1800]                    mov dx,OFFSET ovl_err_text
  3362 0000135C B92400                      mov cx,36
  3363 0000135F EB82                        jmp SHORT D.D._ovl_err_shared ; jump to code shared with DOS error
  3364                                  
  3365                                  D.D._ovl_op_error     ENDP
  3366                                  
  3367                                  ;*****************************
  3368                                  ;* _OVLMGR_CLOSE_OVL_FILE    *
  3369                                  ;*****************************
  3370                                  
  3371                                  ; provide a way for application to externally close overlay file
  3372                                  ; returns ax==dos error code if unsuccessful close
  3373                                  ; destroys ax
  3374                                  
  3375                                  _ovlmgr_close_ovl_file  PROC    FAR
  3376 00001361 1E                          push    ds              ; save critical register
  3377 00001362 53                          push    bx
  3378 00001363 B8[ssss]                    mov ax,D.D._ovl_data
  3379 00001366 8ED8                        mov ds,ax               ; ds -> overlay manager data
  3380 00001368 8B1E[2401]                  mov bx,[D.D._ovl_file_handle]   ; get handle of overlay file
  3381 0000136C 09DB                        or  bx,bx               ; make sure nonzero (valid handle)
  3382 0000136E 7404                        je  oco_2               ; zero, file not open
  3383 00001370 B43E                        mov ah,3eh              ; close file
  3384 00001372 CD21                        int 21h
  3385                                  
  3386                                  oco_2:
  3387 00001374 5B                          pop bx
  3388 00001375 1F                          pop ds
  3389 00001376 CB                          ret
  3390                                  _ovlmgr_close_ovl_file  ENDP
  3391                                  
  3392                                  ;*****************************
  3393                                  ;* _OVLMGR_OPEN_OVL_FILE     *
  3394                                  ;*****************************
  3395                                  
  3396                                  ; provide a way for application to externally open overlay file
  3397                                  ; returns ax==dos error code if unsuccessful open
  3398                                  ; destroys ax
  3399                                  
  3400                                  _ovlmgr_open_ovl_file   PROC    FAR
  3401 00001377 1E                          push    ds              ; save critical register
  3402 00001378 52                          push    dx
  3403 00001379 BA[ssss]                    mov dx,D.D._ovl_data
  3404 0000137C 8EDA                        mov ds,dx
  3405 0000137E BA[4600]                    mov dx,OFFSET _ovlmgr_overlay_filename  ; ds:dx -> filename to open
  3406 00001381 B8403D                      mov ax,3d40h            ; open file for read access
  3407 00001384 CD21                        int 21h
  3408 00001386 A3[2401]                    mov [D.D._ovl_file_handle],ax   ; save overlay file handle, if no error
  3409 00001389 7202                        jc  ooo_ret             ; error occurred
  3410 0000138B 31C0                        xor ax,ax               ; zero file handle, indicate no errors on return
  3411                                  
  3412                                  ooo_ret:
  3413 0000138D 5A                          pop dx
  3414 0000138E 1F                          pop ds
  3415 0000138F CB                          ret
  3416                                  _ovlmgr_open_ovl_file   ENDP
  3417                                  
  3418                                  ;*****************************
  3419                                  ;* _OVLMGR_FREE_EMS          *
  3420                                  ;*****************************
  3421                                  
  3422                                  ; provide a way for application to free EMS used by overlay manager
  3423                                  ; returns ah==EMS error code if unsuccessful
  3424                                  ; destroys ax
  3425                                  
  3426                                  _ovlmgr_free_ems    PROC    FAR
  3427                                  _om_fr_ems  EQU $
  3428 00001390 1E                          push    ds              ; save critical register
  3429 00001391 52                          push    dx
  3430 00001392 BA[ssss]                    mov dx,D.D._ovl_data
  3431 00001395 8EDA                        mov ds,dx
  3432                                  
  3433 00001397 31C0                        xor ax,ax               ; assume no error
  3434 00001399 3806[7B09]                  cmp [D.D._ovl_ems_pool_flag],al ; see if any EMS to free
  3435 0000139D 740A                        je  ofe_ret             ; no
  3436                                  
  3437 0000139F 8B16[8C09]                  mov dx,[D.D._ovl_ox_handle]	; get EMS handle for /ox
  3438 000013A3 30C0                        xor al,al
  3439 000013A5 B445                        mov ah,45h              ; release handle and memory pages
  3440 000013A7 CD67                        int 67h
  3441                                  
  3442                                  ofe_ret:
  3443 000013A9 5A                          pop dx
  3444 000013AA 1F                          pop ds
  3445 000013AB CB                          ret
  3446                                  _ovlmgr_free_ems    ENDP
  3447                                  
  3448                                  ;*****************************
  3449                                  ;* NEW_TERMINATE             *
  3450                                  ;*****************************
  3451                                  
  3452                                  ; perform termination code
  3453                                  ; destroys no registers
  3454                                  
  3455                                  new_terminate   PROC    FAR
  3456 000013AC 50                          push    ax              ; save all used registers
  3457 000013AD 53                          push    bx
  3458 000013AE 52                          push    dx
  3459 000013AF 1E                          push    ds
  3460 000013B0 0E                          push cs
  3461 000013B1 E8DCFF                  	call    _ovlmgr_free_ems	; NASM port far call with push cs
  3462                                  
  3463 000013B4 B8[ssss]                    mov ax,D.D._ovl_data
  3464 000013B7 8ED8                        mov ds,ax
  3465 000013B9 8B16[990B]                  mov dx,[orport_handle]
  3466 000013BD 803E[7D09]00                cmp byte [D.D._ovl_orp],0        ; see if expanded memory to free
  3467 000013C2 7404                        je  nt_2                ; no
  3468 000013C4 B445                        mov ah,45h              ; release EMS handle and pages
  3469 000013C6 CD67                        int 67h
  3470                                  
  3471                                  nt_2:
  3472 000013C8 803E[7C09]00                cmp byte [D.D._ovl_ort],0        ; see if extended memory to free
  3473 000013CD 7406                        je  nt_3                ; no
  3474 000013CF B40A                        mov ah,0ah              ; free extended memory block
  3475 000013D1 FF1E[9D0B]                  call    far [xms_addr]
  3476                                  
  3477                                  nt_3:
  3478 000013D5 803E[8209]00                cmp byte [D.D._ovl_umb],0        ; see if UMB to free
  3479 000013DA 7412                        je  nt_4                ; no
  3480 000013DC 803E[5A01]00            	cmp	byte [dos5_umb_flag],0		; see if DOS 5 umb
  3481 000013E1 750B                    	jne	nt_4				; yes, don't go through XMS
  3482 000013E3 B411                        mov ah,11h              ; free upper memory block
  3483 000013E5 2E8B16[0A00]            	mov	dx,[cs:D.D._ovl_load_start]	; get segment base of block
  3484 000013EA FF1E[9D0B]                  call    far [xms_addr]
  3485                                  
  3486                                  nt_4:
  3487 000013EE 8B16[9B0B]                  mov dx,[ohpoht_handle]
  3488 000013F2 803E[7F09]00                cmp byte [D.D._ovl_oht],0        ; see if XMS to free
  3489 000013F7 7406                        je  nt_5                ; no
  3490 000013F9 B40A                        mov ah,0ah              ; free extended memory block
  3491 000013FB FF1E[9D0B]                  call    far [xms_addr]
  3492                                  
  3493                                  nt_5:
  3494 000013FF 803E[7E09]00                cmp byte [D.D._ovl_ohp],0        ; see if EMS to free
  3495 00001404 7404                        je  nt_6                ; no
  3496 00001406 B445                        mov ah,45h              ; release EMS handle and pages
  3497 00001408 CD67                        int 67h
  3498                                  
  3499                                  nt_6:
  3500 0000140A 1F                          pop ds
  3501 0000140B 5A                          pop dx
  3502 0000140C 5B                          pop bx
  3503 0000140D 58                          pop ax
  3504 0000140E 2EFF2E[3E00]                jmp far [cs:psp_terminate]  ; transfer to old terminate address
  3505                                  new_terminate   ENDP
  3506                                  
  3507                                  ;*****************************
  3508                                  ;* UMB_CHECK_SETUP           *
  3509                                  ;*****************************
  3510                                  
  3511                                  ; check if UMB is available, get largest if so
  3512                                  ; returns carry flag set on error, reset if okay
  3513                                  ; destroys bx,cx
  3514                                  
  3515                                  umb_check_setup	PROC	NEAR
  3516 00001413 50                      	push	ax
  3517 00001414 52                      	push	dx				; save critical register
  3518                                  
  3519 00001415 E8E501                      call    xms_check_setup ; check that XMS exists, setup if so
  3520 00001418 7212                        jc  ucs_noumb           ; carry if error
  3521 0000141A B410                    	mov	ah,10h				; allocate upper memory block
  3522 0000141C BAFEFF                  	mov	dx,0fffeh			; force failure
  3523 0000141F FF1E[9D0B]                  call    far [xms_addr]
  3524 00001423 8916[A10B]              	mov	[umb_avail],dx		; save largest size available
  3525 00001427 80FBB0                  	cmp	bl,0b0h				; error code must be smaller UMB available or no UMB
  3526 0000142A 7456                    	je	ucs_ret				; okay
  3527                                  
  3528                                  ; error accessing UMB, check if DOS 5 UMB's exist
  3529                                  ucs_noumb:
  3530 0000142C B80030                  	mov	ax,3000h			; get dos version number
  3531 0000142F CD21                    	int	21h
  3532 00001431 3C05                    	cmp	al,5				; see if version 5 or greater
  3533 00001433 7248                    	jb	ucs_cancel			; no
  3534                                  
  3535 00001435 B80058                  	mov	ax,5800h			; get memory allocation strategy
  3536 00001438 CD21                    	int	21h
  3537 0000143A 7241                    	jc	ucs_cancel			; error occurred
  3538 0000143C 88C2                    	mov	dl,al				; save old strategy in dl
  3539 0000143E B80258                  	mov	ax,5802h			; get UMB link state
  3540 00001441 CD21                    	int	21h
  3541 00001443 7238                    	jc	ucs_cancel			; error occurred
  3542 00001445 88C6                    	mov	dh,al				; save link state in dh
  3543                                  
  3544 00001447 BB4000                  	mov	bx,40h				; high memory first fit
  3545 0000144A B80158                  	mov	ax,5801h			; set allocation strategy
  3546 0000144D CD21                    	int	21h
  3547 0000144F 722C                    	jc	ucs_cancel			; error occurred
  3548 00001451 BB0100                  	mov	bx,1				; UMB's part of memory chain
  3549 00001454 B80358                  	mov	ax,5803h			; set UMB link state
  3550 00001457 CD21                    	int	21h
  3551 00001459 BBFEFF                  	mov	bx,0fffeh			; force failure
  3552 0000145C B448                    	mov	ah,48h				; allocate memory
  3553 0000145E CD21                    	int	21h					; will always give error, bx has largest free
  3554 00001460 891E[A10B]              	mov	[umb_avail],bx
  3555 00001464 88F3                    	mov	bl,dh				; get old link state
  3556 00001466 30FF                    	xor	bh,bh				; zero high byte
  3557 00001468 B80358                  	mov	ax,5803h			; set UMB link state
  3558 0000146B CD21                    	int	21h
  3559 0000146D 88D3                    	mov	bl,dl				; get old strategy
  3560 0000146F 30FF                    	xor	bh,bh				; zero high byte
  3561 00001471 B80158                  	mov	ax,5801h			; set allocation strategy
  3562 00001474 CD21                    	int	21h
  3563 00001476 C606[5A01]01            	mov	byte [dos5_umb_flag],1		; flag dos 5 umbs in use
  3564 0000147B EB05                    	jmp	SHORT ucs_ret
  3565                                  
  3566                                  ; no XMS UMB'S, no DOS 5 UMB's
  3567                                  ucs_cancel:
  3568 0000147D C606[8209]00                mov byte [D.D._ovl_umb],0        ; reset UMB flag
  3569                                  
  3570                                  ucs_ret:
  3571 00001482 5A                      	pop	dx					; restore critical register
  3572 00001483 58                      	pop	ax
  3573 00001484 C3                      	ret
  3574                                  umb_check_setup	ENDP
  3575                                  
  3576                                  ;*****************************
  3577                                  ;* UMB_POOL_ALLOC            *
  3578                                  ;*****************************
  3579                                  
  3580                                  ; allocate UMB for overlay pool
  3581                                  ; upon entry cx==pool size in paras
  3582                                  ; destroys ax,bx,cx
  3583                                  
  3584                                  umb_pool_alloc	PROC	NEAR
  3585 00001485 52                      	push	dx				; save critical register
  3586 00001486 803E[5A01]00            	cmp	byte [dos5_umb_flag],0		; see if dos 5 umb allocation
  3587 0000148B 744B                    	je	upa_not5			; no
  3588                                  
  3589                                  ; use DOS 5 memory chain linked umb
  3590 0000148D B80058                  	mov	ax,5800h			; get memory allocation strategy
  3591 00001490 CD21                    	int	21h
  3592 00001492 723F                    	jc	upa_dos5bomb		; error occurred
  3593 00001494 88C2                    	mov	dl,al				; save old strategy in dl
  3594 00001496 B80258                  	mov	ax,5802h			; get UMB link state
  3595 00001499 CD21                    	int	21h
  3596 0000149B 7236                    	jc	upa_dos5bomb		; error occurred
  3597 0000149D 88C6                    	mov	dh,al				; save link state in dh
  3598                                  
  3599 0000149F B80158                  	mov	ax,5801h			; set allocation strategy
  3600 000014A2 BB4000                  	mov	bx,40h				; high memory first fit
  3601 000014A5 CD21                    	int	21h
  3602 000014A7 722A                    	jc	upa_dos5bomb		; error occurred
  3603 000014A9 BB0100                  	mov	bx,1				; UMB's part of memory chain
  3604 000014AC B80358                  	mov	ax,5803h			; set UMB link state
  3605 000014AF CD21                    	int	21h
  3606 000014B1 89CB                    	mov	bx,cx				; get number of paras to allocate
  3607 000014B3 B448                    	mov	ah,48h				; allocate memory
  3608 000014B5 CD21                    	int	21h
  3609 000014B7 9C                      	pushf					; save allocation error flag (must reset old strategy)
  3610 000014B8 50                      	push	ax				; save segment of allocated block
  3611 000014B9 88F3                    	mov	bl,dh				; get old link state
  3612 000014BB 30FF                    	xor	bh,bh				; zero high byte
  3613 000014BD B80358                  	mov	ax,5803h			; set UMB link state
  3614 000014C0 CD21                    	int	21h
  3615 000014C2 88D3                    	mov	bl,dl				; get old strategy in bx
  3616 000014C4 30FF                    	xor	bh,bh				; zero high byte
  3617 000014C6 B80158                  	mov	ax,5801h			; set allocation strategy
  3618 000014C9 CD21                    	int	21h
  3619 000014CB 5B                      	pop	bx					; bx == segment of allocated block
  3620 000014CC 9D                      	popf					; restore allocation error status
  3621 000014CD 7204                    	jc	upa_dos5bomb		; error occurred during allocation
  3622                                  
  3623 000014CF 89CA                    	mov	dx,cx				; cx holds paras allocated
  3624 000014D1 EB10                    	jmp	SHORT upa_update	; success, update overlay variables
  3625                                  
  3626                                  ; previous DOS 5 UMB size determination bombed during allocation
  3627                                  ; VERY SLEAZY, POP OFF RETURN ADDRESS AND JUMP BACK TO NO UMB CODE
  3628                                  upa_dos5bomb:
  3629 000014D3 5A                      	pop	dx					; restore dx
  3630 000014D4 58                      	pop	ax					; kill return address
  3631 000014D5 E9D4EC                  	jmp	NEAR PTR init_noumb	; nasty kludge jump back
  3632                                  
  3633                                  upa_not5:
  3634 000014D8 B410                    	mov	ah,10h				; allocate upper memory block
  3635 000014DA 89CA                    	mov	dx,cx				; get paras to allocate
  3636 000014DC FF1E[9D0B]                  call    far [xms_addr]
  3637 000014E0 E87404                      call    check_xms_error ; see if error occurred
  3638                                  
  3639                                  upa_update:
  3640 000014E3 89D0                    	mov	ax,dx				; get paras allocated
  3641 000014E5 A3[0601]                    mov [D.D._ovl_amt_alloc],ax ; save amount of memory allocated
  3642 000014E8 48                          dec ax                  ; make relative zero
  3643 000014E9 B105                    	mov	cl,5
  3644 000014EB D3E8                    	shr	ax,cl				; convert to 512 blocks, /32
  3645 000014ED 40                          inc ax                  ; adjust for beginning block
  3646 000014EE A3[0801]                    mov [D.D._ovl_amt_512],ax   ; save 512 blocks allocated
  3647                                  
  3648 000014F1 89D8                    	mov	ax,bx				; get overlay load area segment
  3649 000014F3 2EA3[0A00]                  mov [cs:D.D._ovl_load_start],ax
  3650 000014F7 0306[0601]                  add ax,[D.D._ovl_amt_alloc] ; calculate paragraph just above overlay load area
  3651 000014FB 2EA3[0C00]                  mov [cs:D.D._ovl_load_end],ax   ; save to memory variable
  3652 000014FF 5A                      	pop	dx					; restore critical register
  3653 00001500 C3                      	ret
  3654                                  umb_pool_alloc	ENDP
  3655                                  
  3656                                  ;*****************************
  3657                                  ;* EMS_CHECK_SETUP           *
  3658                                  ;*****************************
  3659                                  
  3660                                  ; check if EMS is available, setup if so
  3661                                  ; returns carry flag set on error, reset if okay
  3662                                  ; destroys ax,bx
  3663                                  
  3664                                  ems_check_setup	PROC	NEAR
  3665 00001501 50                      	push	ax
  3666 00001502 52                      	push	dx
  3667 00001503 BA[9009]                    mov dx,OFFSET emmname   ; ds:dx -> device name
  3668 00001506 B8003D                      mov ax,3d00h            ; open for reading
  3669 00001509 CD21                        int 21h
  3670 0000150B 723F                        jc  ecs_noems           ; open failed
  3671                                  
  3672 0000150D 89C3                        mov bx,ax               ; bx holds handle
  3673 0000150F B80044                      mov ax,4400h            ; IOCTL get device info
  3674 00001512 CD21                        int 21h
  3675 00001514 7236                        jc  ecs_noems           ; IOCTL call failed
  3676                                  
  3677 00001516 80E280                      and dl,80h              ; get high bit, set if char device
  3678 00001519 7431                        je  ecs_noems           ; file device
  3679                                  
  3680 0000151B B80744                      mov ax,4407h            ; IOCTL get output status
  3681 0000151E CD21                        int 21h
  3682 00001520 722A                        jc  ecs_noems           ; IOCTL call failed
  3683                                  
  3684 00001522 B43E                        mov ah,3eh              ; close file
  3685 00001524 CD21                        int 21h
  3686 00001526 7224                        jc  ecs_noems           ; close failed
  3687                                  
  3688 00001528 B440                        mov ah,40h              ; get EMS system status
  3689 0000152A CD67                        int 67h                 ; call EMM
  3690 0000152C 08E4                        or  ah,ah               ; check for EMM error
  3691 0000152E 751C                        jne ecs_noems           ; EMM error occurred
  3692                                  
  3693 00001530 B446                        mov ah,46h              ; get EMM version
  3694 00001532 CD67                        int 67h
  3695 00001534 08E4                        or  ah,ah               ; check for error
  3696 00001536 7514                        jne ecs_noems           ; error occurred
  3697 00001538 3C30                        cmp al,30h              ; must be EMS version 3.0 or greater
  3698 0000153A 7210                        jb	ecs_noems           ; bad version
  3699                                  
  3700 0000153C B441                        mov ah,41h              ; get page frame address
  3701 0000153E CD67                        int 67h
  3702 00001540 08E4                        or  ah,ah
  3703 00001542 7508                        jne ecs_noems           ; EMM error occurred
  3704                                  
  3705 00001544 891E[8E09]                  mov [D.D._ovl_ems_base],bx  ; save EMS base (page frame)
  3706 00001548 F8                      	clc						; clear carry flag to show no error
  3707 00001549 5A                      	pop	dx
  3708 0000154A 58                      	pop	ax
  3709 0000154B C3                      	ret
  3710                                  
  3711                                  ecs_noems:
  3712 0000154C F9                      	stc						; set carry flag to show error
  3713 0000154D 5A                      	pop	dx
  3714 0000154E 58                      	pop	ax
  3715 0000154F C3                      	ret
  3716                                  ems_check_setup	ENDP
  3717                                  
  3718                                  ;*****************************
  3719                                  ;* OVL_EMS_POOLCHECK         *
  3720                                  ;*****************************
  3721                                  
  3722                                  ; check if EMS is available for overlay pool, if not reset $$_ovl_ems_pool_flag
  3723                                  ; destroys bx
  3724                                  
  3725                                  ovl_ems_poolcheck	PROC    NEAR
  3726 00001550 50                          push    ax              ; save critical register
  3727 00001551 52                          push    dx
  3728                                  
  3729                                  ; check if /ox e-var is set
  3730 00001552 A0[5B09]                    mov al,[D.D._ovl_ox_evar]   ; see if environment variable set for /ox
  3731 00001555 08C0                        or  al,al
  3732 00001557 7441                        je  oec_chkemm          ; no, bypass check for proper setting
  3733                                  
  3734                                  ; check the environment block for the /ox e-var
  3735 00001559 06                          push    es
  3736 0000155A 56                          push    si
  3737 0000155B 31F6                        xor si,si               ; starting location for target string check
  3738 0000155D 26A12C00                    mov ax,[es:2ch]         ; get environment segment from offset 2ch in PSP
  3739 00001561 85C0                    	test ax, ax		; environment valid ?
  3740 00001563 742F                    	jz ox_fail		; no -->
  3741 00001565 8EC0                        mov es,ax               ; es -> environment segment
  3742                                  
  3743                                  ox_find_evar:
  3744 00001567 31DB                        xor bx,bx               ; offset into target string
  3745                                  
  3746                                  ox_loop:
  3747 00001569 268A04                      mov al,[es:si]          ; get byte from environment string, point to next
  3748 0000156C 46                          inc si                  ; point to next char in environment
  3749 0000156D 3A87[5B09]                  cmp al,[bx+OFFSET D.D._ovl_ox_evar]   ; does environment char match ox string char
  3750 00001571 7407                        je  ox_byte_match       ; yes, try next location
  3751 00001573 260A04                      or  al,[es:si]          ; two zero values in a row mean the end of the environment
  3752 00001576 75EF                        jne ox_find_evar        ; not the end of the environment
  3753 00001578 EB1A                        jmp SHORT ox_fail       ; at end of environment, no ox environment char
  3754                                  
  3755                                  ; check that /ox e-var is not part of another environment string
  3756                                  ox_byte_match:
  3757 0000157A 09DB                        or  bx,bx               ; bx is zero if first char is matched
  3758 0000157C 750C                        jne ox_2                ; not first char, test already done
  3759 0000157E 83FE01                      cmp si,1                ; si equals one if e-var is first string in environment block
  3760 00001581 7407                        je  ox_2                ; no previous environment string
  3761 00001583 26807CFE00                  cmp BYTE PTR [es:si-2],0    ; check if char before e-var was nonzero
  3762 00001588 75DD                        jne ox_find_evar        ; yes, e-var is a subset of another string, keep looking
  3763                                  
  3764                                  ox_2:
  3765 0000158A 43                          inc bx                  ; a match, move to next byte of target string
  3766 0000158B 80BF[5B09]00                cmp BYTE PTR [bx+OFFSET D.D._ovl_ox_evar],0   ; see if at end of target
  3767 00001590 75D7                        jne ox_loop             ; not yet, keep comparing
  3768 00001592 EB04                        jmp SHORT ox_success    ; matched
  3769                                  
  3770                                  ox_fail:
  3771 00001594 5E                          pop si
  3772 00001595 07                          pop es
  3773 00001596 EB07                        jmp SHORT oec_noems     ; fail EMS usage
  3774                                  
  3775                                  ox_success:
  3776 00001598 5E                          pop si
  3777 00001599 07                          pop es
  3778                                  
  3779                                  oec_chkemm:
  3780 0000159A E864FF                  	call	ems_check_setup	; get EMS status
  3781 0000159D 7308                    	jnc	oec_checkmem		; checked out okay
  3782                                  
  3783                                  ; no, or can't use, EMS
  3784                                  oec_noems:
  3785 0000159F C606[7B09]00                mov byte [D.D._ovl_ems_pool_flag],0	; reset EMS flag
  3786                                  
  3787                                  oec_ret:
  3788 000015A4 5A                          pop dx                  ; restore critical register
  3789 000015A5 58                          pop ax
  3790 000015A6 C3                          ret
  3791                                  
  3792                                  oec_checkmem:
  3793 000015A7 B442                        mov ah,42h              ; get number of pages
  3794 000015A9 CD67                        int 67h
  3795 000015AB 08E4                        or  ah,ah
  3796 000015AD 75F0                        jne oec_noems           ; error occurred, don't use EMS
  3797 000015AF 83FB04                      cmp bx,4                ; see if at least 4 unused EMS pages
  3798 000015B2 72EB                        jb  oec_noems           ; no
  3799 000015B4 BB0400                      mov bx,4                ; only allocate four pages
  3800 000015B7 B443                        mov ah,43h              ; allocate handle and pages
  3801 000015B9 CD67                        int 67h
  3802 000015BB 08E4                        or  ah,ah
  3803 000015BD 75E0                        jne oec_noems           ; error occurred
  3804                                  
  3805 000015BF 8916[8C09]                  mov [D.D._ovl_ox_handle],dx	; save handle, if successful
  3806                                  
  3807                                  ; map in pages to use logical page 0->0, 1->1, 2->2, 3->3
  3808 000015C3 31DB                        xor bx,bx
  3809 000015C5 88D8                        mov al,bl
  3810 000015C7 B444                        mov ah,44h              ; map expanded memory page
  3811 000015C9 CD67                        int 67h
  3812 000015CB 08E4                        or  ah,ah               ; see if error occurred
  3813 000015CD 75D0                        jne oec_noems           ; error occurred
  3814                                  
  3815 000015CF BB0100                      mov bx,1
  3816 000015D2 88D8                        mov al,bl
  3817 000015D4 B444                        mov ah,44h              ; map expanded memory page
  3818 000015D6 CD67                        int 67h
  3819 000015D8 08E4                        or  ah,ah               ; see if error occurred
  3820 000015DA 75C3                        jne oec_noems           ; error occurred
  3821                                  
  3822 000015DC BB0200                      mov bx,2
  3823 000015DF 88D8                        mov al,bl
  3824 000015E1 B444                        mov ah,44h              ; map expanded memory page
  3825 000015E3 CD67                        int 67h
  3826 000015E5 08E4                        or  ah,ah               ; see if error occurred
  3827 000015E7 75B6                        jne oec_noems           ; error occurred
  3828                                  
  3829 000015E9 BB0300                      mov bx,3
  3830 000015EC 88D8                        mov al,bl
  3831 000015EE B444                        mov ah,44h              ; map expanded memory page
  3832 000015F0 CD67                        int 67h
  3833 000015F2 08E4                        or  ah,ah               ; see if error occurred
  3834 000015F4 75A9                        jne oec_noems           ; error occurred
  3835                                  
  3836 000015F6 C606[8209]00            	mov	byte [D.D._ovl_umb],0		; reset UMB overlay pool flag
  3837 000015FB EBA7                        jmp SHORT oec_ret       ; done
  3838                                  
  3839                                  ovl_ems_poolcheck	ENDP
  3840                                  
  3841                                  ;*****************************
  3842                                  ;* XMS_CHECK_SETUP           *
  3843                                  ;*****************************
  3844                                  
  3845                                  ; check that XMS exists, setup if so
  3846                                  ; returns carry flag set on error, reset if okay
  3847                                  ; destroys bx,cx
  3848                                  
  3849                                  xms_check_setup PROC    NEAR
  3850 000015FD 50                          push    ax
  3851 000015FE 52                          push    dx
  3852 000015FF 06                          push    es
  3853 00001600 B80043                      mov ax,4300h            ; check if XMM is present
  3854 00001603 CD2F                        int 2fh                 ; multiplex interrupt
  3855 00001605 3C80                        cmp al,80h              ; check if driver present
  3856 00001607 7512                        jne xcs_noxms           ; no
  3857                                  
  3858 00001609 B81043                      mov ax,4310h            ; get XMS driver entry point
  3859 0000160C CD2F                        int 2fh
  3860 0000160E 891E[9D0B]                  mov WORD PTR [xms_addr],bx    ; save it
  3861 00001612 8C06[9F0B]                  mov WORD PTR [xms_addr+2],es
  3862 00001616 F8                          clc						; return success indication
  3863                                  
  3864                                  xcs_ret:
  3865 00001617 07                          pop es
  3866 00001618 5A                          pop dx
  3867 00001619 58                          pop ax
  3868 0000161A C3                          ret
  3869                                  
  3870                                  ; no, or can't use, XMS
  3871                                  xcs_noxms:
  3872 0000161B F9                          stc                     ; set carry flag to indicate error
  3873 0000161C EBF9                        jmp SHORT xcs_ret
  3874                                  
  3875                                  xms_check_setup ENDP
  3876                                  
  3877                                  ;*****************************
  3878                                  ;* GET_XMS_FOR_ORT           *
  3879                                  ;*****************************
  3880                                  
  3881                                  ; allocate 128K XMS for /ort overlay swapout, if possible
  3882                                  ; destroys bx,cx
  3883                                  
  3884                                  get_xms_for_ort PROC	NEAR
  3885 0000161E 50                          push    ax
  3886 0000161F 52                          push    dx
  3887 00001620 06                          push    es
  3888 00001621 E8D9FF                      call    xms_check_setup ; check that XMS exists, setup if so
  3889 00001624 7218                        jc  gxt_noort           ; carry if error
  3890                                  
  3891 00001626 BA8000                      mov dx,128              ; allocate 128K for active overlay swapping
  3892 00001629 B409                        mov ah,9                ; allocate extended memory block
  3893 0000162B FF1E[9D0B]                  call    far [xms_addr]
  3894 0000162F 09C0                        or  ax,ax               ; see if error
  3895 00001631 740B                        je  gxt_noort           ; yes, don't use XMS for ort
  3896                                  
  3897 00001633 8916[990B]                  mov [orport_handle],dx
  3898 00001637 C606[7D09]00                mov byte [D.D._ovl_orp],0        ; reset EMS flag as XMS is used
  3899 0000163C EB05                        jmp SHORT gxt_ret
  3900                                  
  3901                                  gxt_noort:
  3902 0000163E C606[7C09]00                mov byte [D.D._ovl_ort],0        ; reset XMS flag
  3903                                  
  3904                                  gxt_ret:
  3905 00001643 07                          pop es
  3906 00001644 5A                          pop dx
  3907 00001645 58                          pop ax
  3908 00001646 C3                          ret
  3909                                  get_xms_for_ort ENDP
  3910                                  
  3911                                  ;*****************************
  3912                                  ;* GET_XMS_FOR_OHT           *
  3913                                  ;*****************************
  3914                                  
  3915                                  ; allocate XMS for /oht overlay file stashing, if possible
  3916                                  ; use $$_oht_size, $$_oht_flag, and $$_ovl_file_size to
  3917                                  ;  compute stash size to allocate
  3918                                  ; destroys ax,bx,cx,dx
  3919                                  
  3920                                  get_xms_for_oht	PROC	NEAR
  3921 00001647 E8B3FF                      call    xms_check_setup ; check that XMS exists, setup if so
  3922 0000164A 7266                        jc  gxh_nooht           ; carry if error
  3923                                  
  3924 0000164C B408                        mov ah,8                ; query free memory
  3925 0000164E FF1E[9D0B]                  call    far [xms_addr]
  3926 00001652 09C0                        or  ax,ax               ; see if error
  3927 00001654 745C                        je  gxh_nooht           ; yes, don't use XMS for /orh
  3928 00001656 83F850                  	cmp	ax,80				; must be at least 80K XMS free in one block
  3929 00001659 7257                    	jb	gxh_nooht
  3930                                  
  3931 0000165B 803E[8109]00            	cmp	byte [D.D._oht_flag],0		; see if leave amount free
  3932 00001660 740B                    	je	gxh_leave			; yes
  3933                                  
  3934                                  ; allocate up to specified amount, ax holds K free, $$_oht_size holds K to allocate
  3935 00001662 3B06[8809]              	cmp	ax,[D.D._oht_size]		; see if more than enough free to allocate to amount
  3936 00001666 7612                    	jbe	gxh_alloc			; no, use amount free
  3937 00001668 A1[8809]                	mov	ax,[D.D._oht_size]		; allocate amount free
  3938 0000166B EB0D                    	jmp	SHORT gxh_alloc
  3939                                  
  3940                                  ; leave free the amount of XMS in $$_oht_size
  3941                                  gxh_leave:
  3942 0000166D 8B16[8809]              	mov	dx,[D.D._oht_size]		; amount must leave free
  3943 00001671 29D0                    	sub	ax,dx				; back off of total amount allocatable
  3944 00001673 723D                    	jc	gxh_nooht			; not enough free
  3945 00001675 83F850                  	cmp	ax,80				; must be at least 80K XMS still free
  3946 00001678 7238                    	jb	gxh_nooht
  3947                                  
  3948                                  ; ax holds amount to allocate, up to $$_ovl_file_size
  3949                                  gxh_alloc:
  3950 0000167A 3B06[8A09]              	cmp	ax,[D.D._ovl_file_size]	; see if amount to allocate > overlay file size
  3951 0000167E 7603                    	jbe	gxh_doalloc			; no
  3952 00001680 A1[8A09]                	mov	ax,[D.D._ovl_file_size]	; only allocate up to overlay file size
  3953                                  
  3954                                  gxh_doalloc:
  3955 00001683 89C2                    	mov	dx,ax				; requested block size in dx
  3956 00001685 89C1                    	mov	cx,ax				; save size in K
  3957 00001687 B409                    	mov	ah,9				; allocate extended memory block
  3958 00001689 FF1E[9D0B]                  call    far [xms_addr]
  3959 0000168D 09C0                        or  ax,ax               ; see if error
  3960 0000168F 7421                        je  gxh_nooht           ; yes, don't use XMS for ort
  3961                                  
  3962 00001691 8916[9B0B]                  mov [ohpoht_handle],dx
  3963                                  
  3964                                  ; convert 1K block count in cx to byte count in ax:cx (shift left 10 bits, *1024)
  3965 00001695 30E4                    	xor	ah,ah
  3966 00001697 88E8                    	mov	al,ch
  3967 00001699 88CD                    	mov	ch,cl
  3968 0000169B 88E1                    	mov	cl,ah				; register moves do effective *256
  3969 0000169D D1E1                    	shl	cx,1
  3970 0000169F D1D0                    	rcl	ax,1
  3971 000016A1 D1E1                    	shl	cx,1
  3972 000016A3 D1D0                    	rcl	ax,1				; ax:cx==1024*block count
  3973 000016A5 890E[A30B]              	mov	WORD PTR [emsxms_free],cx
  3974 000016A9 A3[A50B]                	mov	WORD PTR [emsxms_free+2],ax
  3975 000016AC C606[7E09]00            	mov	byte [D.D._ovl_ohp],0		; reset EMS file stashing flag
  3976 000016B1 C3                      	ret
  3977                                  
  3978                                  gxh_nooht:
  3979 000016B2 C606[7F09]00                mov byte [D.D._ovl_oht],0        ; reset XMS file stashing flag
  3980 000016B7 C3                      	ret
  3981                                  get_xms_for_oht	ENDP
  3982                                  
  3983                                  ;*****************************
  3984                                  ;* OVL_LIM40_CHECK           *
  3985                                  ;*****************************
  3986                                  
  3987                                  ; check that EMS version 4.0 (with lower memory mapping) exists
  3988                                  ; returns carry flag set on error, reset if okay
  3989                                  ; destroys ax,bx,dx
  3990                                  
  3991                                  lim_ems40_check	PROC	NEAR
  3992 000016B8 E846FE                  	call	ems_check_setup	; get EMS status
  3993 000016BB 720E                        jc  olc_noems           ; EMS access failed
  3994                                  
  3995 000016BD B446                        mov ah,46h              ; get EMM version
  3996 000016BF CD67                        int 67h
  3997 000016C1 08E4                        or  ah,ah               ; check for error
  3998 000016C3 7506                        jne olc_noems           ; error occurred
  3999 000016C5 3C40                        cmp al,40h              ; must be EMS version 4.0 or greater
  4000 000016C7 7202                        jb  olc_noems           ; no
  4001                                  
  4002 000016C9 F8                          clc						; return success indication
  4003 000016CA C3                      	ret
  4004                                  
  4005                                  ; no, or can't use, EMS 4.0
  4006                                  olc_noems:
  4007 000016CB F9                          stc                     ; set carry flag to indicate error
  4008 000016CC C3                      	ret
  4009                                  lim_ems40_check	ENDP
  4010                                  
  4011                                  ;*****************************
  4012                                  ;* GET_EMS_FOR_ORP           *
  4013                                  ;*****************************
  4014                                  
  4015                                  ; allocate 128K EMS for /orp overlay swapout, if possible
  4016                                  ; destroys bx
  4017                                  
  4018                                  get_ems_for_orp	PROC    NEAR
  4019 000016CD 50                          push    ax
  4020 000016CE 52                          push    dx
  4021 000016CF E8E6FF                  	call	lim_ems40_check	; get LIM EMS 4.0 status
  4022 000016D2 721A                        jc  gep_noems           ; EMS access failed
  4023                                  
  4024 000016D4 BB0800                      mov bx,8                ; allocate 8 16K pages (128K)
  4025 000016D7 B443                        mov ah,43h
  4026 000016D9 CD67                        int 67h
  4027 000016DB 08E4                        or  ah,ah               ; check for error
  4028 000016DD 750F                        jne gep_noems           ; error occurred
  4029                                  
  4030 000016DF 8916[990B]                  mov [orport_handle],dx
  4031 000016E3 8916[D00B]                  mov [xbuff + xs_shandle],dx
  4032 000016E7 8916[D70B]                  mov [xbuff + xs_dhandle],dx
  4033                                  
  4034                                  gep_ret:
  4035 000016EB 5A                          pop dx
  4036 000016EC 58                          pop ax
  4037 000016ED C3                          ret
  4038                                  
  4039                                  ; no, or can't use, EMS
  4040                                  gep_noems:
  4041 000016EE C606[7D09]00                mov byte [D.D._ovl_orp],0        ; reset EMS flag
  4042 000016F3 EBF6                        jmp SHORT gep_ret
  4043                                  
  4044                                  get_ems_for_orp	ENDP
  4045                                  
  4046                                  ;*****************************
  4047                                  ;* GET_EMS_FOR_OHP           *
  4048                                  ;*****************************
  4049                                  
  4050                                  ; allocate EMS 4.0 pages for /ohp overlay file stashing, if possible
  4051                                  ; use $$_ohp_size, $$_ohp_flag, and $$_ovl_file_size to
  4052                                  ;  compute stash size to allocate
  4053                                  ; destroys ax,bx,cx,dx
  4054                                  
  4055                                  get_ems_for_ohp	PROC	NEAR
  4056 000016F5 E809FE                  	call	ems_check_setup	; check for EMS 3.0 availability
  4057 000016F8 7218                        jc  gfp_noohp           ; EMS access failed
  4058                                  
  4059 000016FA E8BBFF                  	call	lim_ems40_check	; get LIM EMS 4.0 status
  4060 000016FD 7305                        jnc gfp_2				; EMS 4.0 available
  4061                                  
  4062 000016FF C606[8309]01            	mov	byte [D.D._ems3_flag],1		; set EMS 3.0 compability mode
  4063                                  
  4064                                  gfp_2:
  4065 00001704 803E[7B09]00            	cmp	byte [D.D._ovl_ems_pool_flag],0	; see if overlay pool in EMS page frame
  4066 00001709 740D                    	je	gfp_3				; no
  4067 0000170B 803E[8309]00            	cmp	byte [D.D._ems3_flag],0		; see if EMS 3.0 compatibility mode
  4068 00001710 7406                    	je	gfp_3				; no
  4069                                  
  4070                                  ; cannot have overlay pool in EMS page frame and use EMS 3.0 overlay file stashing
  4071                                  ; no, or can't use, EMS
  4072                                  gfp_noohp:
  4073 00001712 C606[7E09]00                mov byte [D.D._ovl_ohp],0        ; reset EMS flag
  4074 00001717 C3                      	ret
  4075                                  
  4076                                  gfp_3:
  4077 00001718 B442                    	mov	ah,42h				; get number of pages
  4078 0000171A CD67                    	int	67h
  4079 0000171C 08E4                        or  ah,ah               ; check for error
  4080 0000171E 75F2                        jne gfp_noohp           ; error occurred
  4081 00001720 83FB05                  	cmp	bx,5				; must at least 80K EMS free (5 pages)
  4082 00001723 72ED                    	jb	gfp_noohp
  4083                                  
  4084 00001725 A1[8609]                	mov	ax,[D.D._ohp_size]		; get stash size in K
  4085 00001728 83C00F                  	add	ax,15				; round up to next 16K page
  4086 0000172B B104                    	mov	cl,4
  4087 0000172D D3E8                    	shr	ax,cl				; /16, convert to 16K pages
  4088                                  
  4089 0000172F 803E[8009]00            	cmp	byte [D.D._ohp_flag],0		; see if leave amount free
  4090 00001734 7408                    	je	gfp_leave			; yes
  4091                                  
  4092                                  ; allocate up to specified amount, ax holds pages to allocate, bx holds pages free
  4093 00001736 39C3                    	cmp	bx,ax				; see if more than enough free to allocate to amount
  4094 00001738 760D                    	jbe	gfp_alloc			; no, use amount free
  4095 0000173A 89C3                    	mov	bx,ax				; allocate amount free
  4096 0000173C EB09                    	jmp	SHORT gfp_alloc
  4097                                  
  4098                                  ; leave free the amount of EMS in $$_ohp_size
  4099                                  gfp_leave:
  4100 0000173E 29C3                    	sub	bx,ax				; back off amount to leave free from total amount allocatable
  4101 00001740 72D0                    	jc	gfp_noohp			; not enough free
  4102 00001742 83FB05                  	cmp	bx,5				; must be at least 5 pages EMS still free
  4103 00001745 72CB                    	jb	gfp_noohp
  4104                                  
  4105                                  ; bx holds number of pages to allocate, up to $$_ovl_file_size
  4106                                  gfp_alloc:
  4107 00001747 A1[8A09]                	mov	ax,[D.D._ovl_file_size]	; get overlay file size in K
  4108 0000174A 83C00F                  	add	ax,15				; round up to next 16K page
  4109 0000174D B104                    	mov	cl,4
  4110 0000174F D3E8                    	shr	ax,cl				; /16, convert to 16K pages
  4111                                  
  4112                                  ; ax holds overlay file size in 16K blocks
  4113 00001751 39C3                    	cmp	bx,ax				; check if amount to allocate > overlay file size
  4114 00001753 7602                    	jbe	gfp_doalloc			; no
  4115 00001755 89C3                    	mov	bx,ax				; only allocate up to overlay file size
  4116                                  
  4117                                  gfp_doalloc:
  4118 00001757 B443                    	mov	ah,43h				; allocate handle and pages
  4119 00001759 CD67                    	int	67h
  4120 0000175B 08E4                        or  ah,ah               ; check for error
  4121 0000175D 75B3                        jne gfp_noohp           ; error occurred
  4122                                  
  4123 0000175F 8916[9B0B]                  mov [ohpoht_handle],dx
  4124                                  
  4125                                  ; convert 16K pages allocated in bx to byte count,
  4126                                  ; make bx high word then shift right 2 bits (shift left 14 bits or *16384)
  4127 00001763 31C0                    	xor	ax,ax
  4128 00001765 D1EB                    	shr	bx,1
  4129 00001767 D1D8                    	rcr	ax,1
  4130 00001769 D1EB                    	shr	bx,1
  4131 0000176B D1D8                    	rcr	ax,1				; byte count in bx:ax
  4132 0000176D A3[A30B]                	mov	WORD PTR [emsxms_free],ax
  4133 00001770 891E[A50B]              	mov	WORD PTR [emsxms_free+2],bx
  4134 00001774 C3                      	ret
  4135                                  get_ems_for_ohp	ENDP
  4136                                  
  4137                                  ;*****************************
  4138                                  ;* CHK_XMSEMS_SWAPOUT        *
  4139                                  ;*****************************
  4140                                  
  4141                                  ; upon entry es -> overlay loaded array entry
  4142                                  ; destroys ax,di,si
  4143                                  
  4144                                  chk_xmsems_swapout  PROC    NEAR
  4145 00001775 A0[7C09]                    mov al,[D.D._ovl_ort]
  4146 00001778 0A06[7D09]                  or  al,[D.D._ovl_orp]
  4147 0000177C 7501                        jne cxs_2               ; active overlay swapout exists
  4148 0000177E C3                          ret
  4149                                  
  4150                                  cxs_2:
  4151 0000177F 53                          push    bx
  4152 00001780 51                          push    cx
  4153 00001781 52                          push    dx
  4154 00001782 06                          push    es
  4155 00001783 26A10800                    mov ax,[es:8]
  4156 00001787 262B060600                  sub ax,[es:6]           ; get size of overlay in paras
  4157                                  
  4158 0000178C 48                          dec ax                  ; make relative zero
  4159 0000178D B105                        mov cl,5
  4160 0000178F D3E8                        shr ax,cl               ; size of overlay in 512 blocks, relative 0
  4161 00001791 40                          inc ax                  ; make relative 1
  4162 00001792 89C3                        mov bx,ax               ; bx holds entry count in table (512 block size)
  4163 00001794 BE[9909]                    mov si,OFFSET xe_table
  4164 00001797 89F2                        mov dx,si               ; dx will track loading area (first zero entry) in case overlay doesn't fit
  4165                                  
  4166                                  cxs_search1:
  4167 00001799 89D9                        mov cx,bx
  4168 0000179B 89C8                        mov ax,cx               ; get current block
  4169 0000179D 48                          dec ax                  ; make relative zero
  4170 0000179E 01C0                        add ax,ax               ; make word offset
  4171 000017A0 01F0                        add ax,si               ; ax holds last entry that will be checked
  4172 000017A2 3D[990B]                    cmp ax,OFFSET xe_table+512  ; see if past end of table
  4173 000017A5 7311                        jae cxs_3               ; yes
  4174                                  
  4175                                  cxs_search2:
  4176 000017A7 AD                          lodsw                   ; get overlay id from entry
  4177 000017A8 09C0                        or  ax,ax               ; see if nonzero
  4178 000017AA 75ED                        jne cxs_search1         ; yes, reset count of overlay blocks to search through
  4179 000017AC 89F2                        mov dx,si               ; save load area
  4180                                  
  4181                                  cxs_nextent:
  4182 000017AE E2F7                        loop    cxs_search2     ; loop through all entries
  4183                                  
  4184                                  ; found enough zero entries to store current overlay
  4185 000017B0 89D8                        mov ax,bx               ; get entry count
  4186 000017B2 01C0                        add ax,ax               ; word/entry
  4187 000017B4 29C2                        sub dx,ax               ; dx -> load area entry
  4188 000017B6 EB29                        jmp SHORT cxs_stash
  4189                                  
  4190                                  ; not enough zero entries to store current overlay, use dx as start of store
  4191                                  cxs_3:
  4192 000017B8 26A10000                    mov ax,[es:0]           ; get overlay identifier
  4193 000017BC 1E                          push    ds
  4194 000017BD 07                          pop es
  4195 000017BE 89D9                        mov cx,bx               ; cx holds overlay size in 512 blocks
  4196 000017C0 89D7                        mov di,dx               ; es:di -> start of active overlay stash area
  4197                                  
  4198                                  cxs_loop:
  4199 000017C2 83F901                      cmp cx,1                ; see if zero'ing last entry
  4200 000017C5 7502                        jne cxs_4               ; no
  4201 000017C7 8B35                        mov si,[di]             ; get last entry value
  4202                                  
  4203                                  cxs_4:
  4204 000017C9 AB                          stosw                   ; update active overlay stash table entry
  4205 000017CA E2F6                        loop    cxs_loop
  4206                                  
  4207                                  ; si holds last entry value, zero any following entries with same value
  4208 000017CC 89F0                        mov ax,si
  4209                                  
  4210                                  cxs_loop2:
  4211 000017CE 81FF[990B]                  cmp di,OFFSET xe_table+512  ; see if at end of table
  4212 000017D2 730B                        jae cxs_5               ; yes
  4213 000017D4 AF                          scasw                   ; see if a match
  4214 000017D5 7508                        jne cxs_5               ; no
  4215 000017D7 26C745FE0000                mov WORD PTR [es:di-2],0    ; zero out entry (clean out partial)
  4216 000017DD EBEF                        jmp SHORT cxs_loop2
  4217                                  
  4218                                  cxs_5:
  4219 000017DF 07                          pop es                  ; restore es -> overlay load array entry
  4220 000017E0 06                          push    es
  4221                                  
  4222                                  ; dx -> start of active overlay stash area
  4223                                  ; bx holds 512 block size
  4224                                  cxs_stash:
  4225 000017E1 89D7                        mov di,dx
  4226 000017E3 26A10000                    mov ax,[es:0]
  4227 000017E7 1E                          push    ds
  4228 000017E8 07                          pop es
  4229 000017E9 89D9                        mov cx,bx
  4230 000017EB F3AB                        rep stosw               ; update active overlay stash table
  4231                                  
  4232                                  ; now copy the overlay out to XMS/EMS memory
  4233 000017ED 89D8                        mov ax,bx
  4234 000017EF B109                        mov cl,9                ; x512
  4235 000017F1 D3E0                        shl ax,cl               ; ax holds bytes to load
  4236 000017F3 07                          pop es                  ; restore es -> overlay load array entry
  4237 000017F4 06                          push    es
  4238                                  
  4239 000017F5 81EA[9909]                  sub dx,OFFSET xe_table  ; adjust relative to start of table
  4240 000017F9 89D6                        mov si,dx
  4241 000017FB B106                        mov cl,6
  4242 000017FD D3EE                        shr si,cl               ; si holds EMS logical page of active overlay  start
  4243 000017FF 31C9                        xor cx,cx               ; convert entry count in dx into bytes in cx:dx
  4244 00001801 88D6                        mov dh,dl               ; register move does effective x256 value multiply
  4245 00001803 30D2                        xor dl,dl               ; zero low byte
  4246                                  
  4247                                  ;***    shr cx,1                ; /2 (256 bytes)
  4248                                  ;***    rcr dx,1
  4249                                  
  4250 00001805 803E[7C09]00                cmp byte [D.D._ovl_ort],0        ; see if swapped to extended memory
  4251 0000180A 7431                        je  cxs_expand          ; no
  4252                                  
  4253                                  ; swapped in extended memory
  4254 0000180C A3[AB0B]                    mov WORD PTR [emb + es_len],ax
  4255 0000180F 31C0                        xor ax,ax
  4256 00001811 A3[AD0B]                    mov WORD PTR [emb + es_len+2],ax
  4257 00001814 A3[AF0B]                    mov [emb + es_src_handle],ax
  4258 00001817 A3[B10B]                    mov WORD PTR [emb + es_src_offset],ax
  4259 0000181A 8916[B70B]                  mov WORD PTR [emb + es_dest_offset],dx
  4260 0000181E 890E[B90B]                  mov WORD PTR [emb + es_dest_offset+2],cx
  4261 00001822 A1[990B]                    mov ax,[orport_handle]
  4262 00001825 A3[B50B]                    mov [emb + es_dest_handle],ax
  4263 00001828 26A10600                    mov ax,[es:6]           ; load segment
  4264 0000182C A3[B30B]                    mov WORD PTR [emb + es_src_offset+2],ax
  4265                                  
  4266 0000182F B40B                        mov ah,0bh              ; move extended memory block
  4267 00001831 BE[AB0B]                    mov si,OFFSET emb       ; ds:si -> parameter block
  4268 00001834 FF1E[9D0B]                  call    far [xms_addr]
  4269 00001838 E81C01                      call    check_xms_error ; see if error occurred
  4270 0000183B EB31                        jmp SHORT cxs_ret
  4271                                  
  4272                                  ; swapped in expanded memory
  4273                                  cxs_expand:
  4274 0000183D A3[CB0B]                    mov WORD PTR [xbuff + xs_len],ax
  4275 00001840 31C0                        xor ax,ax
  4276 00001842 A3[CD0B]                    mov WORD PTR [xbuff + xs_len+2],ax
  4277 00001845 A2[CF0B]                    mov [xbuff + xs_stype],al
  4278 00001848 A3[D20B]                    mov [xbuff + xs_soffset],ax
  4279 0000184B 26A10600                    mov ax,[es:6]
  4280 0000184F A3[D40B]                    mov [xbuff + xs_ssegpage],ax
  4281 00001852 C606[D60B]01                mov byte [xbuff + xs_dtype],1
  4282 00001857 81E2FF3F                    and dx,03fffh           ; round to 16K page
  4283 0000185B 8916[D90B]                  mov [xbuff + xs_doffset],dx
  4284 0000185F 8936[DB0B]                  mov [xbuff + xs_dsegpage],si
  4285                                  
  4286 00001863 B80057                      mov ax,5700h            ; move memory region
  4287 00001866 BE[CB0B]                    mov si,OFFSET xbuff     ; ds:si -> parameter block
  4288 00001869 CD67                        int 67h
  4289 0000186B E8FA00                  	call	check_ems_error
  4290                                  
  4291                                  cxs_ret:
  4292 0000186E 07                          pop es
  4293 0000186F 5A                          pop dx
  4294 00001870 59                          pop cx
  4295 00001871 5B                          pop bx
  4296 00001872 C3                          ret
  4297                                  chk_xmsems_swapout  ENDP
  4298                                  
  4299                                  ;*****************************
  4300                                  ;* XMSEMS_SWAPIN             *
  4301                                  ;*****************************
  4302                                  
  4303                                  ; returns al != 0 if successful swap-in from swapout area
  4304                                  ; destroys ax,bx,cx,dx,es
  4305                                  
  4306                                  xmsems_swapin   PROC    NEAR
  4307 00001873 57                          push    di
  4308 00001874 56                          push    si
  4309 00001875 A0[7C09]                    mov al,[D.D._ovl_ort]
  4310 00001878 0A06[7D09]                  or  al,[D.D._ovl_orp]
  4311 0000187C 7505                        jne xs_2                ; active overlay stashing exists
  4312                                  
  4313                                  xs_fail:
  4314 0000187E 30C0                        xor al,al
  4315 00001880 5E                          pop si
  4316 00001881 5F                          pop di
  4317 00001882 C3                          ret
  4318                                  
  4319                                  xs_2:
  4320 00001883 B90001                      mov cx,256
  4321 00001886 1E                          push    ds
  4322 00001887 07                          pop es
  4323 00001888 BF[9909]                    mov di,OFFSET xe_table  ; di will offset into stash table
  4324 0000188B 2EA1[2600]                  mov ax,[cs:jump_segment]  ; ax holds overlay identifier
  4325 0000188F F2AF                        repne   scasw
  4326 00001891 75EB                        jne xs_fail             ; not found
  4327                                  
  4328                                  ; at least 512 bytes of segment stashed
  4329 00001893 26C745FE0000                mov WORD PTR [es:di-2],0    ; zero out swapped in overlay from stash
  4330 00001899 B90100                      mov cx,1
  4331 0000189C 89FA                        mov dx,di
  4332 0000189E 81EA[9B09]                  sub dx,OFFSET xe_table+2    ; dx holds starting block word offset
  4333                                  
  4334                                  xs_loop:
  4335 000018A2 81FF[990B]                  cmp di,OFFSET xe_table+512  ; see if at end of stash table
  4336 000018A6 730C                        jae xs_3                ; yes
  4337 000018A8 AF                          scasw                   ; see if next entry matches too
  4338 000018A9 7509                        jne xs_3                ; no
  4339 000018AB 26C745FE0000                mov WORD PTR [es:di-2],0    ; zero out swapped in overlay from stash
  4340 000018B1 41                          inc cx                  ; bump count of K stashes
  4341 000018B2 EBEE                        jmp SHORT xs_loop
  4342                                  
  4343                                  ; cx holds 512 bytes to load
  4344                                  xs_3:
  4345 000018B4 89C8                        mov ax,cx
  4346 000018B6 B105                        mov cl,5
  4347 000018B8 D3E0                        shl ax,cl               ; ax holds paragraphs
  4348 000018BA A3[3401]                    mov [ofh_ovl_size],ax     ; fake out overlay manager, giving amount as read in size
  4349 000018BD B104                        mov cl,4
  4350 000018BF D3E0                        shl ax,cl               ; ax holds bytes to load
  4351                                  
  4352 000018C1 89D6                        mov si,dx
  4353 000018C3 B106                        mov cl,6
  4354 000018C5 D3EE                        shr si,cl               ; si holds EMS logical page of stash start
  4355 000018C7 31C9                        xor cx,cx               ; convert entry offset in dx into bytes in cx:dx
  4356 000018C9 88D6                        mov dh,dl               ; register move does effective x256 value multiply
  4357 000018CB 30D2                        xor dl,dl               ; zero low byte
  4358                                  
  4359                                  ;***    shr cx,1                ; /2 (256 bytes)
  4360                                  ;***    rcr dx,1
  4361                                  
  4362 000018CD 803E[7C09]00                cmp byte [D.D._ovl_ort],0        ; see if stashed in extended memory
  4363 000018D2 7430                        je  xs_expand           ; no
  4364                                  
  4365                                  ; swapped in extended memory
  4366 000018D4 A3[AB0B]                    mov WORD PTR [emb + es_len],ax
  4367 000018D7 31C0                        xor ax,ax
  4368 000018D9 A3[AD0B]                    mov WORD PTR [emb + es_len+2],ax
  4369 000018DC A3[B50B]                    mov [emb + es_dest_handle],ax
  4370 000018DF A3[B70B]                    mov WORD PTR [emb + es_dest_offset],ax
  4371 000018E2 8916[B10B]                  mov WORD PTR [emb + es_src_offset],dx
  4372 000018E6 890E[B30B]                  mov WORD PTR [emb + es_src_offset+2],cx
  4373 000018EA A1[990B]                    mov ax,[orport_handle]
  4374 000018ED A3[AF0B]                    mov [emb + es_src_handle],ax
  4375 000018F0 A1[3E01]                    mov ax,[D.D._ovl_load_seg]
  4376 000018F3 A3[B90B]                    mov WORD PTR [emb + es_dest_offset+2],ax
  4377                                  
  4378 000018F6 B40B                        mov ah,0bh              ; move extended memory block
  4379 000018F8 BE[AB0B]                    mov si,OFFSET emb       ; ds:si -> parameter block
  4380 000018FB FF1E[9D0B]                  call    far [xms_addr]
  4381 000018FF E85500                      call    check_xms_error ; see if error occurred
  4382 00001902 EB30                        jmp SHORT xs_success
  4383                                  
  4384                                  ; swapped in expanded memory
  4385                                  xs_expand:
  4386 00001904 A3[CB0B]                    mov WORD PTR [xbuff + xs_len],ax
  4387 00001907 31C0                        xor ax,ax
  4388 00001909 A3[CD0B]                    mov WORD PTR [xbuff + xs_len+2],ax
  4389 0000190C A2[D60B]                    mov [xbuff + xs_dtype],al
  4390 0000190F A3[D90B]                    mov [xbuff + xs_doffset],ax
  4391 00001912 A1[3E01]                    mov ax,[D.D._ovl_load_seg]
  4392 00001915 A3[DB0B]                    mov [xbuff + xs_dsegpage],ax
  4393 00001918 C606[CF0B]01                mov byte [xbuff + xs_stype],1
  4394 0000191D 81E2FF3F                    and dx,03fffh           ; round to 16K page
  4395 00001921 8916[D20B]                  mov [xbuff + xs_soffset],dx
  4396 00001925 8936[D40B]                  mov [xbuff + xs_ssegpage],si
  4397                                  
  4398 00001929 B80057                      mov ax,5700h            ; move memory region
  4399 0000192C BE[CB0B]                    mov si,OFFSET xbuff     ; ds:si -> parameter block
  4400 0000192F CD67                        int 67h
  4401 00001931 E83400                  	call	check_ems_error
  4402                                  
  4403                                  xs_success:
  4404                                  
  4405                                  ; maintain load/reload count for profiler
  4406 00001934 2E803E[3600]00              cmp byte [cs:is_calling_ovl], 0  ; load or reload?
  4407 0000193A 740C                        je xs_load_1
  4408 0000193C 8306[EF0B]01                add word [D.D._ovl_load_count+0],1  ; increment load count
  4409 00001941 8316[F10B]00                adc word [D.D._ovl_load_count+2],0
  4410 00001946 EB0A                        jmp SHORT xs_load_2
  4411                                  xs_load_1:
  4412 00001948 8306[F30B]01                add word [D.D._ovl_reload_count+0],1  ; increment reload count
  4413 0000194D 8316[F50B]00                adc word [D.D._ovl_reload_count+2],0
  4414                                  xs_load_2:
  4415                                  
  4416 00001952 B001                        mov al,1
  4417 00001954 5E                          pop si   
  4418 00001955 5F                          pop di
  4419 00001956 C3                          ret
  4420                                  xmsems_swapin   ENDP
  4421                                  
  4422                                  ;*****************************
  4423                                  ;* CHECK_XMS_ERROR           *
  4424                                  ;*****************************
  4425                                  
  4426                                  ; check if XMS error, ax is ZERO if error upon entry
  4427                                  ; if error, bl has xms error upon entry
  4428                                  ; convert ax to warplink error code
  4429                                  
  4430                                  check_xms_error PROC	NEAR
  4431 00001957 09C0                        or  ax,ax
  4432 00001959 7401                        je  cxe_err             ; error occurred
  4433                                  
  4434                                  cxe_ret:
  4435 0000195B C3                          ret
  4436                                  
  4437                                  ; XMS error occurred
  4438                                  cxe_err:
  4439 0000195C 80FBA0                      cmp bl,0a0h             ; see if no more free memory (not really an error)
  4440 0000195F 74FA                        je  cxe_ret             ; no more free memory
  4441 00001961 88D8                        mov al,bl               ; get 8 bit error code in al
  4442 00001963 B401                        mov ah,1
  4443 00001965 E9BFF9                      jmp NEAR PTR D.D._ovl_op_error    ; all XMS errors are fatal, don't return
  4444                                  
  4445                                  check_xms_error ENDP
  4446                                  
  4447                                  ;*****************************
  4448                                  ;* CHECK_EMS_ERROR           *
  4449                                  ;*****************************
  4450                                  
  4451                                  ; check if EMS error, ah is nonzero if error upon entry
  4452                                  ; if error, bl has xms error upon entry
  4453                                  ; convert ax to warplink error code
  4454                                  
  4455                                  check_ems_error PROC	NEAR
  4456 00001968 08E4                        or  ah,ah				; see if error occurred
  4457 0000196A 7501                        jne	cee_err				; yes
  4458 0000196C C3                          ret
  4459                                  
  4460                                  ; EMS error occurred
  4461                                  cee_err:
  4462 0000196D 88E0                        mov al,ah               ; get 8 bit error code in al
  4463 0000196F B402                        mov ah,2
  4464 00001971 E9B3F9                      jmp NEAR PTR D.D._ovl_op_error    ; all EMS errors are fatal, don't return
  4465                                  
  4466                                  check_ems_error ENDP
  4467                                  
  4468                                  ;*****************************
  4469                                  ;* READ_TO_EMS               *
  4470                                  ;*****************************
  4471                                  
  4472                                  ; read from file to EMS transfer buffer, transfer to EMS, if EMS used
  4473                                  ;  otherwise straight file read
  4474                                  ; upon entry ds:dx-> EMS area to transfer to, bx == file handle,
  4475                                  ;  cx holds byte count
  4476                                  ; destroys NO registers other than typical function 3fh return values
  4477                                  
  4478                                  read_to_ems PROC	NEAR
  4479 00001974 1E                          push    ds
  4480 00001975 B8[ssss]                    mov ax,D.D._ovl_data
  4481 00001978 8ED8                        mov ds,ax               ; ds -> overlay manager data
  4482 0000197A 803E[7B09]00                cmp byte [D.D._ovl_ems_pool_flag],0	; see if EMS page frame used for pool
  4483 0000197F 1F                          pop ds
  4484 00001980 7505                        jne	rte_ems				; yes
  4485 00001982 B43F                        mov ah,3fh
  4486 00001984 CD21                        int 21h
  4487 00001986 C3                          ret
  4488                                  
  4489                                  rte_ems:
  4490 00001987 56                          push    si              ; save critical registers
  4491 00001988 57                          push    di
  4492 00001989 06                          push    es
  4493 0000198A 51                          push    cx
  4494 0000198B 52                          push    dx
  4495 0000198C 55                          push    bp
  4496 0000198D 1E                          push    ds
  4497                                  
  4498 0000198E 89D7                        mov di,dx
  4499 00001990 07                          pop es                  ; es:di -> destination (EMS) block
  4500 00001991 06                          push    es              ; restore stack
  4501 00001992 31ED                        xor bp,bp               ; bp holds total bytes read
  4502                                  
  4503                                  rte_readloop:
  4504 00001994 51                          push    cx              ; save bytes to read
  4505 00001995 81F90008                    cmp cx,2048            	; write only 2K chunk max
  4506 00001999 7603                        jbe rte_2
  4507 0000199B B90008                      mov cx,2048
  4508                                  
  4509                                  rte_2:
  4510 0000199E B8[ssss]                    mov ax,D.D._ovl_data
  4511 000019A1 8ED8                        mov ds,ax               ; ds -> overlay manager data
  4512 000019A3 BA[5B01]                	mov	dx,OFFSET ems_trans_block
  4513 000019A6 89D6                    	mov	si,dx
  4514 000019A8 B43F                        mov ah,3fh              ; read file
  4515 000019AA CD21                        int 21h
  4516 000019AC 5A                      	pop	dx					; get bytes to read in dx
  4517 000019AD 721C                        jc  rte_out				; error reading file
  4518                                  
  4519 000019AF 01C5                        add bp,ax               ; update total bytes read
  4520 000019B1 89C1                        mov cx,ax               ; get bytes read in cx
  4521                                  
  4522                                  ; transfer from transfer block to EMS block
  4523 000019B3 D1E9                        shr cx,1                ; convert byte count to write to words
  4524 000019B5 F3A5                        rep movsw               ; move the string
  4525 000019B7 D1D1                        rcl cx,1                ; pick up carry
  4526 000019B9 F3A4                        rep movsb               ; transfer leftover byte, if any
  4527                                  
  4528 000019BB 89D1                        mov cx,dx				; cx==bytes to read
  4529 000019BD 81E90008                    sub cx,2048            	; subtract maximum read
  4530 000019C1 7605                        jbe rte_ret             ; all read
  4531 000019C3 3D0008                      cmp ax,2048				; see if actual bytes read matched requested
  4532 000019C6 74CC                        je  rte_readloop        ; yes, not at end of file
  4533                                  
  4534                                  rte_ret:
  4535 000019C8 F8                      	clc						; clear carry for carry on file read is error checks
  4536 000019C9 89E8                        mov ax,bp               ; get total bytes read in ax
  4537                                  
  4538                                  rte_out:
  4539 000019CB 1F                          pop ds
  4540 000019CC 5D                          pop bp
  4541 000019CD 5A                          pop dx
  4542 000019CE 59                          pop cx
  4543 000019CF 07                          pop es
  4544 000019D0 5F                          pop di
  4545 000019D1 5E                          pop si
  4546 000019D2 C3                          ret
  4547                                  read_to_ems ENDP
  4548                                  
  4549                                  ; (no prior section) ; D.D._ovl_code ENDS
  4550                                  
  4551                                  END
