     1                                  ;*********************************************************************
     2                                  ;*   MLOVLFIL.ASM                                                    *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          12/31/92                                         *
     6                                  ;*   Model:         Small                                            *
     7                                  ;*   Version:       2.5                                              *
     8                                  ;*   Assembler:     MASM 5.0                                         *
     9                                  ;*   Environment:   MS-DOS 2.x+                                      *
    10                                  ;*                                                                   *
    11                                  ;*   linker overlay file routines                                    *
    12                                  ;*                                                                   *
    13                                  ;*********************************************************************
    14                                  
    15                                  ;TITLE   WARPLINK mlovlfil
    16                                  ;PAGE    50,80
    17                                  
    18                                  ;.MODEL  SMALL
    19                                  
    20                                  ;*****************************
    21                                  ;* Include files             *
    22                                  ;*****************************
    23                                  
    24                                  [list -]
    29                                  
    30                                  ;*****************************
    31                                  ;* Public declarations       *
    32                                  ;*****************************
    33                                  
    34                                  ; procedures
    35                                  PUBLIC  setup_ovl_file,write_vectors,flush_ovl_page,ovl_file_write
    36                                  PUBLIC  write_ovl_reloc,flush_reloc_array,get_symbol_segoff
    37                                  PUBLIC  write_clar_data,convert_to_page
    38                                  PUBLIC	safe_xms_addr
    39                                  
    40                                  PUBLIC	read_new_ovl_page
    41                                  
    42                                  ; variables
    43                                  PUBLIC  lookup_segment,ind_segment,segcall_segment
    44                                  PUBLIC  large_ovl_name,is_emsxms_ovl,ems_ovl_to_file
    45                                  PUBLIC  ovl_in_xms,xms_ovl_handle
    46                                  PUBLIC	ovl_filesize
    47                                  
    48                                  ;*****************************
    49                                  ;* Data begins               *
    50                                  ;*****************************
    51                                  
    52                                  .DATA
    53                                  
    54                                  ;*****************************
    55                                  ;* External declarations     *
    56                                  ;*****************************
    57                                  
    58                                  ; variables
    59                                  EXTRN   data_offset:DWORD,ovlpubblk_pos:WORD,no_match_okay:BYTE
    60                                  EXTRN   data_segment:WORD,rec_offset:WORD
    61                                  EXTRN   ems_first_avail:WORD,ems_trans_block:WORD
    62                                  EXTRN   ems_pages_flushed:BYTE
    63                                  
    64                                  ; initialized local variables
    65                                  
    66                                  ; byte values
    67 00000000 00                      is_emsxms_ovl  DB  0		; nonzero if overlay file is in EMS/XMS
    68 00000001 00                      EVEN
    69 00000002 00                      ovl_in_xms  DB  0			; nonzero if overlay file is in XMS only
    70 00000003 00                      EVEN
    71                                  
    72                                  ; word values
    73 00000004 0000                    ovl_idnum   DW  0			; overlay identifier number
    74 00000006 0000                    reloc_ovl_id    DW  0		; overlay owning relocation array
    75 00000008 0000                    reloc_ovl_pos   DW  0		; current position in relocation array
    76 0000000A 0000                    ovl_page_owner  DW  0		; id code of overlay owning overlay page
    77 0000000C 0000                    ovl_page_base   DW  0		; base of overlay page, always on 4K boundary
    78 0000000E 0000                    ovl_high_page_byte  DW  0	; highest byte written to on overlay page
    79 00000010 0000                    lookup_tbl_pos  DW  0		; current position in lookup table array
    80 00000012 0000                    ovl_filesize	DW	0		; size of overlay file in K
    81                                  
    82                                  ; dword values
    83 00000014 00000000                curr_ems_pos    DD  0		; current EMS/XMS write position (analogous to file position)
    84 00000018 00000000                ovl_file_size   DD  0		; size of overlay file
    85                                  
    86                                  ; byte strings
    87                                  
    88 0000001C 000000000000000000-     dirty_bit_table DB  16 DUP (0)	; indicates whether need to read overlay page from disk
    88 00000025 00000000000000     
    89                                  
    90 0000002C 2E                      near_vector_bytes   DB  2eh				; CS:
    91 0000002D 8F06                    					DB  8fh,6			; POP CS:CALL_ADDRESS
    92 0000002F 0000                    near_pop            DB  0,0
    93 00000031 2EFF16                  					DB  2eh,0ffh,16h	; CALL [CS:CALL_ADDRESS]
    94 00000034 0000                    near_call			DB	0,0
    95 00000036 EA                      					DB  0eah			; JMP FAR xxxx:xxxx
    96 00000037 00000000                ret_vector_bytes    DB  0,0,0,0
    97 0000003B 00                      					DB  0				; 1 filler byte
    98                                  
    99 0000003C 53                      shared_vector_bytes DB  53h				; PUSH BX
   100 0000003D BB                      					DB  0bbh			; MOV BX,xxxx
   101 0000003E 0000                    source_id_word      DB  0,0
   102 00000040 51                      					DB  51h				; PUSH CX
   103 00000041 8CC9                    					DB  8ch,0c9h		; MOV CX,CS
   104 00000043 EA                      					DB  0eah			; JMP FAR xxxx:xxxx
   105 00000044 00000000                to_vector_bytes     DB  0,0,0,0
   106 00000048 0000                    					DB  0,0				; CALL_ADDRESS DW ?
   107                                  
   108 0000004A 50                      public_vector_bytes DB  50h				; PUSH AX
   109 0000004B B8                      					DB  0b8h			; MOV AX,xxxx
   110 0000004C 0000                    dest_id_word        DB  0,0
   111 0000004E E9                      					DB  0e9h			; CALL SHARED_VECTOR_CODE
   112 0000004F 0000                    offset_to_shared    DB  0,0
   113                                  
   114                                  ; used by indirect call routine
   115 00000051 EA                      ind_vector_bytes    DB  0eah			; JMP FAR xxxx:xxxx
   116 00000052 00000000                to_2o_bytes         DB  0,0,0,0
   117                                  
   118                                  ; used by segment call routine
   119 00000056 EA                      segcall_vect_bytes  DB  0eah		; JMP FAR xxxx:xxxx
   120 00000057 00000000                to_segcall_bytes    DB  0,0,0,0
   121                                  
   122                                  .DATA?
   123                                  
   124                                  ; uninitialized local variables
   125                                  
   126                                  ; word values
   127 00000000 <res Eh>                ovl_sys_info    DW  7 DUP (?)	; overlay file system info buffer
   128 0000000E ????                    total_ref   DW  ?			; total referenced overlaid publics for segment partition in overlay public block
   129 00000010 ????                    lookup_segment  DW  ?		; segment of overlay lookup table
   130 00000012 ????                    ind_segment DW  ?			; segment of overlay indirect call table
   131 00000014 ????                    segcall_segment DW  ?		; segment of segment call table
   132 00000016 ????                    prev_vect_bytes DW  ?		; previously written vector bytes count for non-overlaid segment
   133 00000018 ????                    nearv_offset    DW  ?		; offset to near vector call for offset
   134 0000001A ????                    ems_first_ovl   DW  ?		; first EMS logical page used by overlay file
   135 0000001C ????                    xms_ovl_handle  DW  ?		; handle for overlay file in XMS
   136                                  ovl_sysblk_ptr  LABEL   WORD	; pointer to temporary block of system information bytes
   136                              <1> ovl_sysblk_ptr :
   137 0000001E ????                    tbuff   DW  ?				; temporary buffer
   138 00000020 ????                    ovl_zeroblk_ptr DW  ?		; pointer to zero'd block of bytes
   139 00000022 ????                    ovl_zeroblk_size	DW	?	; size of zero'd block of bytes
   140                                  
   141                                  ; doubleword values
   142 00000024 ????????                ovl_filepos     DD  ?		; current overlay file pointer position
   143 00000028 ????????                large_ovl_name  DD  ?		; seg:offset of largest overlay segment name
   144                                  
   145                                  ; structures
   146                                  EMPB_STRUC  STRUC
   147 00000000 ????????                	es_len  DD  ?			; length of block in bytes
   148 00000004 ????                    	es_src_handle   DW  ?	; source EMB handle
   149 00000006 ????????                	es_src_offset   DD  ?	; source offset
   150 0000000A ????                    	es_dest_handle  DW  ?	; destination EMB handle
   151 0000000C ????????                	es_dest_offset  DD  ?	; destination offset
   152                                  EMPB_STRUC  ENDS
   153                                  
   154                                  
   155                                  .DATA
   156                                  
   157 0000005B 00                      EVEN
   158                                  ovl_empb:
   159                                  istruc EMPB_STRUC
   160                                  at es_len
   161                                  ovl_empb.es_len:
   162 0000005C 00<rep 4h>              at es_src_handle
   163                                  ovl_empb.es_src_handle:
   164 00000060 00<rep 2h>              at es_src_offset
   165                                  ovl_empb.es_src_offset:
   166 00000062 00<rep 4h>              at es_dest_handle
   167                                  ovl_empb.es_dest_handle:
   168 00000066 00<rep 2h>              at es_dest_offset
   169                                  ovl_empb.es_dest_offset:
   170 00000068 00<rep 4h>              iend
   171                                  
   172                                  ;*****************************
   173                                  ;* Constant data             *
   174                                  ;*****************************
   175                                  
   176                                  .CONST
   177                                  
   178                                  EVEN
   179 00000000 24245F4F564C5F5645-     vector_text     DB  '$$_OVL_VECTOR',0
   179 00000009 43544F5200         
   180 0000000E 24245F4F564C5F5245-     ret_text        DB  '$$_OVL_RET',0
   180 00000017 5400               
   181 00000019 24245F4F564C5F494E-     ovl_2o_text     DB  '$$_OVL_IND_2OVL_ENT',0
   181 00000022 445F324F564C5F454E-
   181 0000002B 5400               
   182 0000002D 24245F4F564C5F5345-     ovl_segcall_text    DB  '$$_OVL_SEG_CALL_ENTRY',0
   182 00000036 475F43414C4C5F454E-
   182 0000003F 54525900           
   183                                  
   184                                  ;*****************************
   185                                  ;* Code begins               *
   186                                  ;*****************************
   187                                  
   188                                  .CODE
   189                                  
   190                                  ;*****************************
   191                                  ;* External declarations     *
   192                                  ;*****************************
   193                                  
   194                                  ; procedures
   195                                  EXTRN   link_error:NEAR,dos_error:NEAR,alloc_memory:NEAR
   196                                  EXTRN   zero_mem_image:NEAR,write_bytes:NEAR,find_pubdecl_entry:NEAR
   197                                  EXTRN   make_reloc_entry:NEAR,map_ems_page:NEAR,restore_ems_map:NEAR
   198                                  EXTRN   read_to_ems:NEAR,check_xms_error:NEAR
   199                                  
   200                                  ;*****************************
   201                                  ;* SETUP_OVL_FILE            *
   202                                  ;*****************************
   203                                  
   204                                  ; create overlay file, allocate 4K memory block for writing to it
   205                                  ; allocate block to hold overlay file positions
   206                                  ; pad to proper length with zero bytes
   207                                  ; destroys ax,bx,cx,dx,di,si,es
   208                                  
   209                                  setup_ovl_file  PROC
   210 00000000 BB0001                  	mov bx,100h				; get 4K block for use in writing to overlay file
   211 00000003 E8(0000)                	call	alloc_memory
   212 00000006 A3[0000]                	mov [ovl_ioblk],ax		; save pointer to block
   213                                  
   214                                  ; zero the 4K block
   215 00000009 8EC0                    	mov es,ax
   216 0000000B 31FF                    	xor di,di				; es:di -> 4K block
   217 0000000D 89F8                    	mov ax,di
   218 0000000F B90008                  	mov cx,2048				; 2K words
   219 00000012 F3AB                    	rep stosw
   220                                  
   221 00000014 A1[0000]                	mov ax,[ovl_count]
   222 00000017 89C2                    	mov dx,ax
   223 00000019 83C003                  	add ax,3				; round up for dword to paragraph conversion
   224 0000001C D1E8                    	shr ax,1				; /2
   225 0000001E D1E8                    	shr ax,1				; /4, 4 dword entries in each paragraph
   226 00000020 89C3                    	mov bx,ax
   227 00000022 E8(0000)                	call	alloc_memory
   228 00000025 A3[0000]                	mov [ovl_filepos_blk],ax	; save file position block segment
   229                                  
   230 00000028 B80A00                  	mov ax,10				; assume non-Clarion (10 bytes/system info)
   231 0000002B 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion
   232 00000030 7403                    	je  sof_alloc			; no
   233 00000032 B80E00                  	mov ax,14				; 14 bytes/system info
   234                                  
   235                                  ; dx holds overlay count, ax holds bytes/system info
   236                                  sof_alloc:
   237 00000035 F7E2                    	mul dx					; get size of system info block to allocate in bytes
   238 00000037 83C00F                  	add ax,15
   239 0000003A 83E0F0                  	and ax,0fff0h			; round up to paragraph boundary
   240                                  
   241                                  ; use memory between allocation_base and allocation_top as temporary storage
   242                                  ; for system information, if not enough room then fail with out of memory
   243 0000003D 8B1E[0000]              	mov bx,[allocation_top]
   244 00000041 2B1E[0000]              	sub bx,[allocation_base]	; free memory in paragraphs
   245 00000045 81FBFF0F                	cmp bx,0fffh			; if at least 64K-16 then enough room
   246 00000049 7312                    	jae sof_memok
   247 0000004B D1E3                    	shl bx,1				; x2
   248 0000004D D1E3                    	shl bx,1				; x4
   249 0000004F D1E3                    	shl bx,1				; x8
   250 00000051 D1E3                    	shl bx,1				; x16, bx holds byte count of free memory
   251 00000053 39C3                    	cmp bx,ax				; see if enough free memory
   252 00000055 7306                    	jae sof_memok			; yes
   253                                  
   254                                  ; force out of memory error
   255                                  sof_oomerr:
   256 00000057 B80800                  	mov ax,8				; force DOS out of memory error
   257 0000005A E9(0000)                	jmp NEAR PTR dos_error
   258                                  
   259                                  sof_memok:
   260 0000005D 89C2                    	mov dx,ax				; save number of bytes used in free memory
   261 0000005F A1[0000]                	mov ax,[allocation_base]
   262 00000062 A3[1E00]                	mov [ovl_sysblk_ptr],ax	; save -> temporary system information storage
   263                                  
   264 00000065 D1EA                    	shr dx,1				; /2, convert number of bytes used to paragraphs
   265 00000067 D1EA                    	shr dx,1				; /4
   266 00000069 D1EA                    	shr dx,1				; /8
   267 0000006B D1EA                    	shr dx,1				; /16
   268 0000006D A1[0000]                	mov ax,[allocation_top]
   269 00000070 2B06[0000]              	sub ax,[allocation_base]	; compute free memory in paragraphs
   270 00000074 29D0                    	sub ax,dx				; compute free memory not used for temporary system information
   271 00000076 3D0001                  	cmp ax,100h				; see if >4K (100h paragraphs)
   272 00000079 770D                    	ja  sof_newzero			; yes
   273                                  
   274                                  ; <4K free memory unused for system info, use 4K block allocated for overlay file i/o
   275 0000007B A1[0000]                	mov ax,[ovl_ioblk]
   276 0000007E A3[2000]                	mov [ovl_zeroblk_ptr],ax
   277 00000081 8EC0                    	mov es,ax
   278 00000083 B90010                  	mov cx,4096
   279 00000086 EB1C                    	jmp SHORT sof_zeroblk
   280                                  
   281                                  sof_newzero:
   282 00000088 B9F0FF                  	mov cx,0fff0h			; preset zero block size to highest amount
   283 0000008B 3DFF0F                  	cmp ax,0fffh			; don't use more than 64K-16 bytes for zero block
   284 0000008E 730A                    	jae sof_newz2
   285 00000090 89C1                    	mov cx,ax
   286 00000092 D1E1                    	shl cx,1				; x2, convert to bytes
   287 00000094 D1E1                    	shl cx,1				; x4
   288 00000096 D1E1                    	shl cx,1				; x8
   289 00000098 D1E1                    	shl cx,1				; x16
   290                                  
   291                                  sof_newz2:
   292 0000009A A1[0000]                	mov ax,[allocation_base]
   293 0000009D 01D0                    	add ax,dx				; compute base of zero block
   294 0000009F A3[2000]                	mov [ovl_zeroblk_ptr],ax	; save it
   295 000000A2 8EC0                    	mov es,ax
   296                                  
   297                                  sof_zeroblk:
   298 000000A4 31FF                    	xor di,di				; es:di -> memory to be zero'ed
   299 000000A6 89F8                    	mov ax,di				; store a zero value
   300 000000A8 890E[2200]              	mov [ovl_zeroblk_size],cx	; save zero block size
   301 000000AC D1E9                    	shr cx,1				; convert byte count to write to words
   302 000000AE F3AB                    	rep stosw				; zero the string
   303 000000B0 D1D1                    	rcl cx,1				; pick up carry
   304 000000B2 F3AA                    	rep stosb				; zero leftover byte, if any
   305                                  
   306 000000B4 8B0E[0000]              	mov cx,[ovl_count]
   307 000000B8 D1E1                    	shl cx,1
   308 000000BA D1E1                    	shl cx,1				; 4 bytes/overlay
   309 000000BC 83C102                  	add cx,2				; adjust for overlay count word
   310 000000BF 890E[1800]              	mov WORD PTR [ovl_file_size],cx	; update overlay file size
   311                                  
   312                                  ; step through each overlaid segment partition entry
   313                                  ; update the overlay identifier number
   314                                  ; write zero word for each of relocation items and zero bytes for total length
   315 000000C3 A1[0000]                	mov ax,[first_segdefblk_ptr]	; get first segdef block pointer
   316                                  
   317                                  segdef_blkloop:
   318 000000C6 09C0                    	or  ax,ax				; see if another block
   319 000000C8 7503                    	jne sof_segblk			; yes
   320 000000CA E92B02                  	jmp NEAR PTR sof_open	; no, open file and write file positions
   321                                  
   322                                  sof_segblk:
   323 000000CD 8EC0                    	mov es,ax				; es -> segdef block
   324 000000CF 06                      	push	es				; keep -> segdef block
   325                                  
   326 000000D0 268B0E0000              	mov cx,[es:0]			; get count of entries in block
   327 000000D5 40                      	inc ax					; bump to first segdef entry in block
   328                                  
   329                                  segdef_entloop:
   330 000000D6 51                      	push	cx				; save entry count on stack
   331 000000D7 8EC0                    	mov es,ax				; es -> segdef entry
   332 000000D9 89C6                    	mov si,ax				; keep -> segdef entry
   333 000000DB 26F6061C0001            	test	BYTE PTR [es:28],1	; see if overlay class
   334 000000E1 7503                    	jne first_segpart		; yes, get first segment partition entry
   335 000000E3 E9FE01                  	jmp NEAR PTR next_segdef	; no
   336                                  
   337                                  ; this segdef is overlay class, check segment partitions owned by it
   338                                  first_segpart:
   339 000000E6 26A11600                	mov ax,[es:22]			; get pointer to first segment partition entry
   340                                  
   341                                  segpart_loop:
   342 000000EA 09C0                    	or  ax,ax				; see if valid segment partition entry
   343 000000EC 7503                    	jne good_segpart		; yes, non-null
   344 000000EE E9F301                  	jmp NEAR PTR next_segdef	; no
   345                                  
   346                                  good_segpart:
   347 000000F1 8EC0                    	mov es,ax				; es -> segment partition entry
   348 000000F3 26A00F00                	mov al,[es:15]
   349 000000F7 2480                    	and al,80h				; get overlaid flag bit
   350 000000F9 7509                    	jne overlaid_segpart	; overlaid
   351 000000FB E9DF01                  	jmp NEAR PTR next_segpart	; not overlaid
   352                                  
   353                                  ; overlay segment too long
   354                                  ovllen_err:
   355 000000FE B83C00                  	mov ax,OVLSEG_LEN_ERR	; overlay segment too long
   356 00000101 E9(0000)                	jmp NEAR PTR link_error	; transfer control to error handler
   357                                  
   358                                  ; overlaid segment, assign overlay identifier number
   359                                  overlaid_segpart:
   360 00000104 FF06[0400]              	inc word [ovl_idnum]			; bump identifier number
   361 00000108 A1[0400]                	mov ax,[ovl_idnum]
   362 0000010B 268B1E0400              	mov bx,[es:4]			; save -> segdef entry in bx
   363 00000110 26A30400                	mov [es:4],ax			; overwrite back pointer to segdef entry with overlay id
   364                                  
   365 00000114 89C7                    	mov di,ax				; di holds overlay id
   366 00000116 4F                      	dec di					; make relative zero
   367 00000117 D1E7                    	shl di,1				; convert to word offset
   368 00000119 8CD8                    	mov ax,ds				; save -> warplink data
   369 0000011B 8E1E[0000]              	mov ds,[master_segblk]	; ds -> master segdef entries block
   370 0000011F 891D                    	mov [di],bx				; save -> master segdef entry in appropriate element
   371 00000121 8ED8                    	mov ds,ax				; restore ds -> warplink data
   372                                  
   373                                  ; see if near/shared vector space was allocated for this segment
   374                                  ; allocate if not
   375 00000123 26F6060F0010            	test	BYTE PTR [es:15],10h	; check vector space allocated flag
   376 00000129 751E                    	jne chk_largest			; set
   377 0000012B 26F6060B0002            	test	BYTE PTR [es:11],2		; see if Big bit set
   378 00000131 75CB                    	jne ovllen_err			; yes, fatal error, segment too large
   379 00000133 2683060C0020            	add WORD PTR [es:12],20h	; add space for vectors
   380 00000139 730E                    	jnc chk_largest			; no overflow
   381 0000013B 26A10C00                	mov ax,[es:12]
   382 0000013F 09C0                    	or  ax,ax				; must be zero for 64K segment
   383 00000141 75BB                    	jne ovllen_err			; segment too long
   384 00000143 26800E0B0002            	or  BYTE PTR [es:11],2	; set Big bit
   385                                  
   386                                  chk_largest:
   387 00000149 26A10C00                	mov ax,[es:12]			; get new overlay size
   388 0000014D 83C00F                  	add ax,15
   389 00000150 83E0F0                  	and ax,0fff0h			; round up to paragraph boundary
   390                                  
   391 00000153 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion switch set
   392 00000158 743F                    	je  sof_3a				; no
   393                                  
   394 0000015A 8B3E[0400]              	mov di,[ovl_idnum]
   395 0000015E 4F                      	dec di					; make relative zero
   396 0000015F D1E7                    	shl di,1
   397 00000161 D1E7                    	shl di,1				; di holds doubleword entry offset for overlay
   398 00000163 1E                      	push	ds				; save critical register
   399 00000164 8E1E[0000]              	mov ds,[data_ovlblk_ptr]	; ds -> get first data overlay block
   400                                  
   401                                  clar_loop:
   402 00000168 81FFFC00                	cmp di,252				; see if entry in current data overlay block (126 word entries)
   403 0000016C 720C                    	jb  clar_curblk			; yes
   404 0000016E 81EFFC00                	sub di,252				; no, get next block, reduce entry count by block amount
   405 00000172 8B0E0000                	mov cx,[0]			; get pointer to next block
   406 00000176 8ED9                    	mov ds,cx				; ds -> next block
   407 00000178 EBEE                    	jmp SHORT clar_loop		; loop until at proper block
   408                                  
   409                                  clar_curblk:
   410 0000017A 8B4D02                  	mov cx,[di+2]			; get _DT segment size
   411 0000017D 8B7D04                  	mov di,[di+4]			; get _DAT segment size
   412 00000180 1F                      	pop ds					; restore critical register
   413 00000181 83C10F                  	add cx,15
   414 00000184 83E1F0                  	and cx,0fff0h			; round up to paragraph boundary
   415 00000187 83C70F                  	add di,15
   416 0000018A 83E7F0                  	and di,0fff0h			; round up to paragraph boundary
   417 0000018D 890E[0000]              	mov [_dt_seg_size],cx		; save segment sizes
   418 00000191 893E[0000]              	mov [_dat_seg_size],di
   419 00000195 01C8                    	add ax,cx				; add them to largest overlay figure
   420 00000197 01F8                    	add ax,di
   421                                  
   422                                  sof_3a:
   423 00000199 3B06[0000]              	cmp ax,[largest_ovl]		; check if should update largest overlay variable
   424 0000019D 7223                    	jb  chk_2nd				; no
   425 0000019F 8B0E[0000]              	mov cx,[largest_ovl]		; keep old largest value
   426 000001A3 A3[0000]                	mov [largest_ovl],ax		; yes, do it
   427 000001A6 890E[0000]              	mov [second_ovl],cx		; old largest to second largest
   428 000001AA 8CC1                    	mov cx,es				; save -> segment partition entry
   429 000001AC 8EC3                    	mov es,bx				; es -> master segdef entry
   430 000001AE 26C4060800              	les ax,[es:8]			; es:ax -> lnames entry
   431 000001B3 83C008                  	add ax,8				; bump ax past doubleword pointers
   432 000001B6 A3[2800]                	mov WORD PTR [large_ovl_name],ax	; save offset of name
   433 000001B9 8CC0                    	mov ax,es
   434 000001BB A3[2A00]                	mov WORD PTR [large_ovl_name+2],ax	; save segment of name
   435 000001BE 8EC1                    	mov es,cx				; restore es -> segment partition entry
   436 000001C0 EB09                    	jmp SHORT get_ovl_offset	; bypass second largest check
   437                                  
   438                                  chk_2nd:
   439 000001C2 3B06[0000]              	cmp ax,[second_ovl]		; check if should update second largest overlay
   440 000001C6 7203                    	jb  get_ovl_offset		; no
   441 000001C8 A3[0000]                	mov [second_ovl],ax		; yes, do it
   442                                  
   443                                  ; save file position
   444                                  get_ovl_offset:
   445 000001CB A1[1800]                	mov ax,WORD PTR [ovl_file_size]
   446 000001CE A3[2400]                	mov WORD PTR [ovl_filepos],ax	; save LSW of file position
   447 000001D1 A1[1A00]                	mov ax,WORD PTR [ovl_file_size+2]
   448 000001D4 A3[2600]                	mov WORD PTR [ovl_filepos+2],ax	; save MSW of file position
   449                                  
   450                                  ; save overlay file system information, structure as follows:
   451                                  ; overlay number DW ?
   452                                  ; offset to overlay code DW ?
   453                                  ; overlay code size in paragraphs DW ?
   454                                  ; IF Clarion, overlay _DT segment size in paragraphs
   455                                  ; IF Clarion, overlay _DAT segment size in paragraphs
   456                                  ; near vector offset DW ?
   457                                  ; relocation entry count DW ?
   458                                  ; relocation entries DW ? DUP (?)
   459                                  ; code DB ? DUP (?)
   460                                  
   461 000001D7 A1[0400]                	mov ax,[ovl_idnum]
   462 000001DA A3[0000]                	mov WORD PTR [ovl_sys_info],ax	; save overlay number
   463 000001DD 26A10C00                	mov ax,[es:12]			; get size of overlay code
   464 000001E1 83C00F                  	add ax,15				; round up
   465 000001E4 7303                    	jnc no_overflow
   466 000001E6 E915FF                  	jmp NEAR PTR ovllen_err	; overflow occurred
   467                                  
   468                                  no_overflow:
   469 000001E9 D1E8                    	shr ax,1				; convert to paragraphs, /2
   470 000001EB D1E8                    	shr ax,1				; /4
   471 000001ED D1E8                    	shr ax,1				; /8
   472 000001EF D1E8                    	shr ax,1				; /16
   473 000001F1 A3[0400]                	mov WORD PTR [ovl_sys_info+4],ax	; size of overlay code in paragraphs
   474                                  
   475 000001F4 268B0E0C00              	mov cx,[es:12]			; get segment length
   476 000001F9 26A10E00                	mov ax,[es:14]			; get vector count
   477 000001FD 80E407                  	and ah,7				; mask off flag bits (only bit 0-2 used)
   478 00000200 BA0700                  	mov dx,7				; 7 bytes per vector
   479 00000203 F7E2                    	mul dx					; dx:ax holds vector bytes, dx always zero
   480 00000205 83C020                  	add ax,20h				; adjust for near/shared vector paragraphs
   481 00000208 29C1                    	sub cx,ax				; cx holds near vector offset value
   482 0000020A 26A10000                	mov ax,[es:0]			; get count of relocation words in ax
   483                                  
   484 0000020E 803E[0000]00            	cmp byte [is_clarion],0		; see if Clarion switch set
   485 00000213 743E                    	je  sof_notclar			; no
   486 00000215 890E[0A00]              	mov WORD PTR [ovl_sys_info+10],cx	; save near vector offset
   487 00000219 A3[0C00]                	mov WORD PTR [ovl_sys_info+12],ax	; save relocation entries count
   488 0000021C 8B0E[0000]              	mov cx,[_dt_seg_size]		; get _DT segment size of this overlay
   489 00000220 010E[1800]              	add WORD PTR [ovl_file_size],cx	; update overlay file size
   490 00000224 8316[1A00]00            	adc WORD [ovl_file_size+2],0	; carry to high word
   491 00000229 D1E9                    	shr cx,1				; convert to paragraphs, /2
   492 0000022B D1E9                    	shr cx,1				; /4
   493 0000022D D1E9                    	shr cx,1				; /8
   494 0000022F D1E9                    	shr cx,1				; /16
   495 00000231 890E[0600]              	mov WORD PTR [ovl_sys_info+6],cx	; save _DT segment size in paragraphs
   496                                  
   497 00000235 8B0E[0000]              	mov cx,[_dat_seg_size]
   498 00000239 010E[1800]              	add WORD PTR [ovl_file_size],cx	; update overlay file size
   499 0000023D 8316[1A00]00            	adc WORD [ovl_file_size+2],0	; carry to high word
   500 00000242 D1E9                    	shr cx,1				; convert to paragraphs, /2
   501 00000244 D1E9                    	shr cx,1				; /4
   502 00000246 D1E9                    	shr cx,1				; /8
   503 00000248 D1E9                    	shr cx,1				; /16
   504 0000024A 890E[0800]              	mov WORD PTR [ovl_sys_info+8],cx	; save _DAT segment size in paragraphs
   505                                  
   506 0000024E B90E00                  	mov cx,14				; 7 system words to write
   507 00000251 EB0A                    	jmp SHORT sof_sysadj
   508                                  
   509                                  sof_notclar:
   510 00000253 890E[0600]              	mov WORD PTR [ovl_sys_info+6],cx	; save near vector offset
   511 00000257 A3[0800]                	mov WORD PTR [ovl_sys_info+8],ax	; save relocation entries count
   512 0000025A B90A00                  	mov cx,10				; 5 system words to  write
   513                                  
   514                                  sof_sysadj:
   515 0000025D D1E0                    	shl ax,1				; convert relocation words to bytes
   516 0000025F 01C8                    	add ax,cx				; adjust for system info bytes
   517 00000261 A3[0200]                	mov WORD PTR [ovl_sys_info+2],ax	; offset to overlay code
   518                                  
   519                                  ; save system information to temporary storage, update overlay file size
   520 00000264 06                      	push	es				; save critical register
   521 00000265 8E06[1E00]              	mov es,[ovl_sysblk_ptr]	; es -> temporary storage
   522 00000269 A1[0400]                	mov ax,[ovl_idnum]
   523 0000026C 48                      	dec ax					; make relative zero
   524 0000026D F7E1                    	mul cx					; ax holds offset into system information
   525 0000026F 89C7                    	mov di,ax				; es:di -> proper system information entry
   526                                  
   527 00000271 A1[0000]                	mov ax,WORD PTR [ovl_sys_info]	; get overlay number
   528 00000274 AB                      	stosw
   529 00000275 A1[0200]                	mov ax,WORD PTR [ovl_sys_info+2]	; offset to overlay code
   530 00000278 AB                      	stosw
   531 00000279 A1[0400]                	mov ax,WORD PTR [ovl_sys_info+4]	; size of overlay code in paragraphs
   532 0000027C AB                      	stosw
   533 0000027D A1[0600]                	mov ax,WORD PTR [ovl_sys_info+6]	; get near vector offset/_DT segment size in paragraphs
   534 00000280 AB                      	stosw
   535 00000281 A1[0800]                	mov ax,WORD PTR [ovl_sys_info+8]	; get relocation entries/_DAT segment size in paragraphs
   536 00000284 AB                      	stosw
   537                                  
   538 00000285 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion switch set
   539 0000028A 7408                    	je  sof_updsize			; no
   540                                  
   541                                  ; clarion system information
   542 0000028C A1[0A00]                	mov ax,WORD PTR [ovl_sys_info+10]	; get near vector offset
   543 0000028F AB                      	stosw
   544 00000290 A1[0C00]                	mov ax,WORD PTR [ovl_sys_info+12]	; get relocation entries count
   545 00000293 AB                      	stosw
   546                                  
   547                                  sof_updsize:
   548 00000294 07                      	pop es					; restore critical register
   549 00000295 010E[1800]              	add WORD PTR [ovl_file_size],cx	; update overlay file size
   550 00000299 8316[1A00]00            	adc WORD [ovl_file_size+2],0	; carry to high word
   551                                  
   552 0000029E 26A10000                	mov ax,[es:0]			; get relocation word count
   553 000002A2 D1E0                    	shl ax,1				; convert to byte count
   554 000002A4 0106[1800]              	add WORD PTR [ovl_file_size],ax	; update overlay file size
   555 000002A8 8316[1A00]00            	adc WORD [ovl_file_size+2],0	; carry to high word
   556                                  
   557 000002AD 26A10C00                	mov ax,[es:12]			; get code size
   558 000002B1 83C00F                  	add ax,15
   559 000002B4 83E0F0                  	and ax,0fff0h			; round up to paragraph boundary
   560 000002B7 0106[1800]              	add WORD PTR [ovl_file_size],ax	; update overlay file size
   561 000002BB 8316[1A00]00            	adc WORD [ovl_file_size+2],0	; carry to high word
   562                                  
   563 000002C0 8B3E[0400]              	mov di,[ovl_idnum]		; get overlay identification number
   564 000002C4 4F                      	dec di					; make relative zero
   565 000002C5 D1E7                    	shl di,1
   566 000002C7 D1E7                    	shl di,1				; convert to doubleword offset
   567 000002C9 A1[2400]                	mov ax,WORD PTR [ovl_filepos]	; get file offset low word
   568 000002CC 8B16[2600]              	mov dx,WORD PTR [ovl_filepos+2]	; get file offset high word
   569 000002D0 8CD9                    	mov cx,ds				; save -> warplink data
   570 000002D2 8E1E[0000]              	mov ds,[ovl_filepos_blk]	; ds -> overlay file positions
   571 000002D6 8905                    	mov [di],ax				; save offset low word
   572 000002D8 895502                  	mov [di+2],dx			; save offset high word
   573 000002DB 8ED9                    	mov ds,cx				; restore ds -> warplink data
   574                                  
   575                                  next_segpart:
   576 000002DD 26A10200                	mov ax,[es:2]			; get pointer to next segment partition entry
   577 000002E1 E906FE                  	jmp NEAR PTR segpart_loop	; loop back and check it
   578                                  
   579                                  next_segdef:
   580 000002E4 59                      	pop cx					; restore entry count from stack
   581 000002E5 89F0                    	mov ax,si				; get old segdef entry
   582 000002E7 83C002                  	add ax,2				; move to next segdef entry in block
   583 000002EA 49                      	dec cx
   584 000002EB 7403                    	je  next_segblk			; all entries in block done
   585 000002ED E9E6FD                  	jmp NEAR PTR segdef_entloop	; get next entry in block
   586                                  
   587                                  next_segblk:
   588 000002F0 07                      	pop es					; restore es -> segdef block
   589 000002F1 26A10200                	mov ax,[es:2]			; get pointer to next block, if any
   590 000002F5 E9CEFD                  	jmp NEAR PTR segdef_blkloop	; loop for next block
   591                                  
   592                                  ; ovl_file_size holds overlay file size in bytes
   593                                  sof_open:
   594 000002F8 E87401                  	call	ems_ovl_setup	; setup ems for overlay file, if possible/available
   595                                  
   596 000002FB BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; DS:DX -> ASCIIZ file specification
   597 000002FE B43C                    	mov ah,3ch				; create/truncate file
   598 00000300 31C9                    	xor cx,cx				; normal file attribute
   599 00000302 CD21                    	int 21h
   600 00000304 E8(0000)                	call	restore_ems_map
   601 00000307 7306                    	jnc sof_2				; no errors
   602                                  
   603                                  sof_to_doserr:
   604 00000309 BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
   605 0000030C E9(0000)                	jmp NEAR PTR dos_error	; error opening file
   606                                  
   607                                  sof_2:
   608 0000030F A3[0000]                	mov [ovl_handle],ax		; save handle of overlay file
   609 00000312 89C3                    	mov bx,ax				; handle in bx for dos calls
   610 00000314 BA[0000]                	mov dx,OFFSET ovl_count wrt DGROUP	; write count of overlays to .OVL file as first word
   611 00000317 B90200                  	mov cx,2				; write two bytes
   612 0000031A 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay stashed in EMS/XMS
   613 0000031F 7405                    	je  sof_noems1			; overlay not stashed in EMS/XMS
   614 00000321 E8320D                  	call	ems_ovl_write	; write to overlay in EMS
   615 00000324 EB10                    	jmp	SHORT sof_fpos
   616                                  
   617                                  sof_noems1:
   618 00000326 B440                    	mov ah,40h				; write to file
   619 00000328 CD21                    	int 21h
   620 0000032A E8(0000)                	call	restore_ems_map
   621 0000032D 72DA                    	jc  sof_to_doserr		; error occurred
   622 0000032F 39C8                    	cmp ax, cx
   623 00000331 B82700                  	mov ax, 27h			; insufficient disk space error
   624 00000334 75D3                    	jne sof_to_doserr
   625                                  
   626                                  ; write overlay file positions saved in ovl_filepos_blk at start of overlay file
   627                                  sof_fpos:
   628 00000336 8B0E[0000]              	mov cx,[ovl_count]
   629 0000033A D1E1                    	shl cx,1
   630 0000033C D1E1                    	shl cx,1				; 4 bytes/overlay
   631 0000033E 1E                      	push	ds				; save critical register
   632 0000033F 31D2                    	xor dx,dx				; ds:dx -> block to write
   633 00000341 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay stashed in EMS/XMS
   634 00000346 8E1E[0000]              	mov ds,[ovl_filepos_blk]	; KEEP FLAGS
   635 0000034A 7405                    	je  sof_noems2			; overlay not stashed in EMS/XMS
   636 0000034C E8070D                  	call	ems_ovl_write	; write to overlay in EMS
   637 0000034F EB10                    	jmp	SHORT sof_syst
   638                                  
   639                                  sof_noems2:
   640 00000351 B440                    	mov ah,40h				; write to file
   641 00000353 CD21                    	int 21h
   642 00000355 E8(0000)                	call	restore_ems_map
   643 00000358 72AF                    	jc  sof_to_doserr		; error occurred
   644 0000035A 39C8                    	cmp ax, cx
   645 0000035C B82700                  	mov ax, 27h			; insufficient disk space error
   646 0000035F 75A8                    	jne sof_to_doserr
   647                                  
   648                                  sof_syst:
   649 00000361 1F                      	pop ds					; restore ds -> warplink data
   650                                  
   651                                  ; read through each file position entry, write system info and zero bytes following
   652 00000362 8E06[1E00]              	mov es,[ovl_sysblk_ptr]
   653 00000366 31F6                    	xor si,si				; es:si -> start of temporary storage
   654 00000368 8B0E[0000]              	mov cx,[ovl_count]
   655                                  
   656                                  sof_writeloop:
   657 0000036C 51                      	push	cx				; save count of overlays to write
   658                                  
   659                                  ; get system identification bytes
   660 0000036D 26AD                    	es lodsw	; overlay id number
   661 0000036F A3[0000]                	mov WORD PTR [ovl_sys_info],ax
   662 00000372 26AD                    	es lodsw	; offset to overlay code
   663 00000374 A3[0200]                	mov WORD PTR [ovl_sys_info+2],ax
   664 00000377 26AD                    	es lodsw	; size of overlay code in paragraphs
   665 00000379 A3[0400]                	mov WORD PTR [ovl_sys_info+4],ax
   666                                  
   667 0000037C 26AD                    	es lodsw	; get near vector offset/_DT segment size
   668 0000037E A3[0600]                	mov WORD PTR [ovl_sys_info+6],ax
   669 00000381 26AD                    	es lodsw	; get relocation entries/_DAT segment size
   670 00000383 A3[0800]                	mov WORD PTR [ovl_sys_info+8],ax
   671                                  
   672 00000386 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion switch set
   673 0000038B 7505                    	jne sof_wrcl			; yes
   674                                  
   675 0000038D B90A00                  	mov cx,10				; system bytes to write
   676 00000390 EB0D                    	jmp SHORT sof_write
   677                                  
   678                                  ; clarion system information
   679                                  sof_wrcl:
   680 00000392 26AD                    	es lodsw	; get near vector offset
   681 00000394 A3[0A00]                	mov WORD PTR [ovl_sys_info+10],ax
   682 00000397 26AD                    	es lodsw	; get relocation entries count
   683 00000399 A3[0C00]                	mov WORD PTR [ovl_sys_info+12],ax
   684                                  
   685 0000039C B90E00                  	mov cx,14				; system bytes to write
   686                                  
   687                                  sof_write:
   688 0000039F BA[0000]                	mov dx,OFFSET ovl_sys_info wrt DGROUP	; ds:dx -> block to write
   689 000003A2 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay stashed in EMS/XMS
   690 000003A7 7405                    	je  sof_noems3			; overlay not stashed in EMS/XMS
   691 000003A9 E8AA0C                  	call	ems_ovl_write	; write to overlay in EMS
   692 000003AC EB10                    	jmp	SHORT sof_code
   693                                  
   694                                  sof_noems3:
   695 000003AE B440                    	mov ah,40h				; write to file
   696 000003B0 CD21                    	int 21h
   697 000003B2 E8(0000)                	call	restore_ems_map
   698 000003B5 7251                    	jc  sof_doserr2			; error occurred
   699 000003B7 39C8                    	cmp ax, cx
   700 000003B9 B82700                  	mov ax, 27h			; insufficient disk space error
   701 000003BC 754A                    	jne sof_doserr2
   702                                  
   703                                  sof_code:
   704 000003BE 8B3E[0400]              	mov di,WORD PTR [ovl_sys_info+4]
   705 000003C2 D1E7                    	shl di,1
   706 000003C4 D1E7                    	shl di,1
   707 000003C6 D1E7                    	shl di,1
   708 000003C8 D1E7                    	shl di,1				; convert paragraphs to bytes
   709 000003CA E86700                  	call	write_zero_to_ovl	; write zeroed bytes for overlay code
   710                                  
   711 000003CD 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion switch set
   712 000003D2 7506                    	jne sof_wrcl2			; yes
   713                                  
   714 000003D4 8B3E[0800]              	mov di,WORD PTR [ovl_sys_info+8]
   715 000003D8 EB22                    	jmp	SHORT sof_reloc		; write zeroed bytes for relocation entries
   716                                  
   717                                  ; clarion specific code
   718                                  sof_wrcl2:
   719 000003DA 8B3E[0600]              	mov di,WORD PTR [ovl_sys_info+6]
   720 000003DE D1E7                    	shl di,1
   721 000003E0 D1E7                    	shl di,1
   722 000003E2 D1E7                    	shl di,1
   723 000003E4 D1E7                    	shl di,1				; convert paragraphs to bytes
   724 000003E6 E84B00                  	call	write_zero_to_ovl	; write zeroed bytes for _DT segment
   725                                  
   726 000003E9 8B3E[0800]              	mov di,WORD PTR [ovl_sys_info+8]
   727 000003ED D1E7                    	shl di,1
   728 000003EF D1E7                    	shl di,1
   729 000003F1 D1E7                    	shl di,1
   730 000003F3 D1E7                    	shl di,1				; convert paragraphs to bytes
   731 000003F5 E83C00                  	call	write_zero_to_ovl	; write zeroed bytes for _DAT segment
   732                                  
   733 000003F8 8B3E[0C00]              	mov di,[ovl_sys_info+12]
   734                                  
   735                                  sof_reloc:
   736 000003FC D1E7                    	shl di,1				; convert word count to bytes
   737 000003FE E83300                  	call	write_zero_to_ovl	; write zeroed bytes for relocation entries
   738                                  
   739                                  sof_nextovl:
   740 00000401 59                      	pop cx					; restore count of overlays to write
   741 00000402 49                      	dec cx
   742 00000403 7409                    	je  sof_wrdone			; all done writing overlays
   743 00000405 E964FF                  	jmp NEAR PTR sof_writeloop	; loop until complete
   744                                  
   745                                  sof_doserr2:
   746 00000408 BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
   747 0000040B E9(0000)                	jmp NEAR PTR dos_error	; error opening file
   748                                  
   749                                  ; get overlay file size (+11 bytes/overlay) in ovl_filesize variable
   750                                  ; bx still == overlay file handle
   751                                  sof_wrdone:
   752                                  %if 0 ;COMMENT #
   753                                  	xor cx,cx				; move file pointer to start of file
   754                                  	mov dx,cx
   755                                  	mov ax,4202h			; move file pointer, offset from file end
   756                                  	int 21h
   757                                  	call	restore_ems_map
   758                                  	mov	cx,ax				; save file size in di:cx
   759                                  	mov	di,dx
   760                                  END COMMENT #
   761                                  %endif
   762                                  ; 12/30/92
   763                                  ; get overlay file size in di:cx
   764 0000040E 8B0E[1800]              	mov	cx,WORD PTR [ovl_file_size]
   765 00000412 8B3E[1A00]              	mov	di,WORD PTR [ovl_file_size+2]
   766                                  
   767 00000416 BA0B00                  	mov	dx,11
   768 00000419 A1[0000]                	mov	ax,[ovl_count]
   769 0000041C F7E2                    	mul	dx					; get overlay count*11 in dx:ax
   770 0000041E 01C8                    	add	ax,cx
   771 00000420 11FA                    	adc	dx,di
   772 00000422 05FF03                  	add	ax,1023
   773 00000425 83D200                  	adc	dx,0				; round up file size in dx:ax to next 1K boundary
   774 00000428 88E0                    	mov	al,ah
   775 0000042A 88D4                    	mov	ah,dl				; register moves effective divide by 256 (assume file size <16M)
   776 0000042C D1E8                    	shr	ax,1				; /512
   777 0000042E D1E8                    	shr	ax,1				; /1024, ax holds file size in K
   778 00000430 A3[1200]                	mov	[ovl_filesize],ax		; save overlay file size in K
   779                                  
   780                                  ;*** feedback required stash amount if EMS or XMS stashing?
   781                                  ;*** 'X EMS pages (XXK) required to completely stash overlay file in EMS.'
   782                                  ;*** 'XK of XMS required to completely stash overlay file in XMS.'
   783                                  
   784 00000433 C3                      	ret
   785                                  setup_ovl_file  ENDP
   786                                  
   787                                  %if 0 ;COMMENT #
   788                                  
   789                                  ;*****************************
   790                                  ;* WRITE_ZERO_TO_OVL         *
   791                                  ;*****************************
   792                                  
   793                                  ; write di zero bytes to overlay file
   794                                  ; upon entry bx holds file handle
   795                                  ; destroys ax,cx,di
   796                                  
   797                                  write_zero_to_ovl   PROC
   798                                  
   799                                  zero_loop:
   800                                  	mov cx,di
   801                                  	cmp cx,[ovl_zeroblk_size]	; only write up to ovl_zeroblk_size bytes each pass thru loop
   802                                  	jbe wz_2				; ovl_zeroblk_size bytes or less to write
   803                                  	mov cx,[ovl_zeroblk_size]
   804                                  
   805                                  wz_2:
   806                                  	push	ds
   807                                  	xor dx,dx
   808                                  	mov ds,[ovl_zeroblk_ptr]	; ds:dx -> zero'd block
   809                                  	mov ah,40h				; write to file
   810                                  	int 21h
   811                                  	pop ds
   812                                  	call	restore_ems_map
   813                                  	jnc .wz_3				; no errors
   814                                  
   815                                  .error:
   816                                  ; error occurred writing file
   817                                  	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
   818                                  	jmp NEAR PTR dos_error	; error opening file
   819                                  
   820                                  .wz_3:
   821                                  	cmp ax, cx
   822                                  	mov ax, 27h			; insufficient disk space error
   823                                  	jne .error
   824                                  	sub di,cx				; subtract number of bytes written this loop pass
   825                                  	jne zero_loop			; more bytes to write, loop back
   826                                  	ret
   827                                  write_zero_to_ovl   ENDP
   828                                  
   829                                  ;*****************************
   830                                  ;* EMS_OVL_SETUP             *
   831                                  ;*****************************
   832                                  
   833                                  ; setup EMS or XMS to hold overlay file if it fits, read it into EMS/XMS
   834                                  ; destroys ax,bx,cx,dx,si,di
   835                                  
   836                                  ems_ovl_setup   PROC
   837                                  	cmp byte [is_xms],0			; see if XMS used
   838                                  	jne eos_chksize			; yes
   839                                  	cmp byte [is_no_ems],0			; see if EMS used
   840                                  	je  eos_chksize			; yes
   841                                  	ret
   842                                  
   843                                  eos_chksize:
   844                                  	mov ax,WORD PTR [ovl_file_size]	; get overlay file size in dx:ax
   845                                  	mov dx,WORD PTR [ovl_file_size+2]
   846                                  	add ax,16383			; round up to nearest 16K boundary
   847                                  	adc dx,0				; carry to high word
   848                                  	call	convert_to_page	; convert bytes in dx:ax to 16K blocks in ax
   849                                  
   850                                  ; check if enough XMS to save overlay file, priority over EMS
   851                                  	cmp byte [is_xms],0			; see if XMS used
   852                                  	je  eos_chkems			; no
   853                                  	mov di,ax				; save 16K block count in di
   854                                  	shl ax,1				; *2
   855                                  	shl ax,1				; *4
   856                                  	shl ax,1				; *8
   857                                  	shl ax,1				; *16, ax holds 1K block count
   858                                  	mov cx,ax				; save 1K block count
   859                                  	mov ah,8				; query free extended memory
   860                                  	call	far [xms_addr]
   861                                  	call	check_xms_error	; see if error occurred
   862                                  	cmp ax,cx				; see if largest free block meets 1K block count
   863                                  	jb  eos_noxms			; no
   864                                  	jmp NEAR PTR eos_usexms	; yes, use XMS
   865                                  
   866                                  eos_ret:
   867                                  	ret
   868                                  
   869                                  ; not enough XMS to stuff overlay file in it, try EMS
   870                                  eos_noxms:
   871                                  	cmp byte [is_no_ems],0			; see if EMS used
   872                                  	jne eos_ret				; no
   873                                  	mov ax,di				; get 16K block count back in ax
   874                                  
   875                                  eos_chkems:
   876                                  	cmp ax,[ems_page_avail]	; see if enough pages are available to hold overlay file
   877                                  	ja	eos_chkflush		; no, see if flushing will work
   878                                  
   879                                  ; enough pages to hold overlay, now see if enough pages for maximum temp file
   880                                  ; (640K) or 40 pages, otherwise flush
   881                                  	mov	bx,[ems_page_avail]
   882                                  	sub	bx,ax
   883                                  	cmp	bx,40				; see if 40 pages left over
   884                                  	jae	eos_emsok			; yes
   885                                  
   886                                  ; not enough ems to hold overlay file+40 pages for temp file if needed,
   887                                  ; check if total ems pages allocated-4
   888                                  ; is enough (if you flush the modules stashed in EMS)
   889                                  eos_chkflush:
   890                                  	mov di,[ems_pagecount]	; get total ems pages
   891                                  	sub di,4				; subtract amount used for file i/o buffer
   892                                  	cmp ax,di				; see if enough total ems pages allocated to hold overlay file
   893                                  	ja  eos_ret				; no
   894                                  	mov byte [ems_pages_flushed],1	; set pages flushed flag
   895                                  	mov word [ems_first_avail],4	; reset first available page flag
   896                                  	mov [ems_page_avail],di	; adjust pages available back to pre-module stashed status
   897                                  	mov di,ax				; save overlay file pages
   898                                  	xor ax,ax				; al holds physical page
   899                                  	mov bx,ax				; bx holds logical page
   900                                  	mov cx,4				; update all 4 pages in ems page frame
   901                                  
   902                                  eos_mapin:
   903                                  	call	map_ems_page	; map 0->0, 1->1, 2->2, 3->3
   904                                  	inc bx					; bump logical page
   905                                  	mov ax,bx				; bump physical page
   906                                  	loop    eos_mapin		; loop until map in complete
   907                                  	mov ax,di				; ax holds overlay file pages
   908                                  
   909                                  eos_emsok:
   910                                  	sub [ems_page_avail],ax	; subtract off pages used by overlay file
   911                                  	mov di,ax				; save overlay page count
   912                                  	mov ax,[ems_first_avail]	; get first available page
   913                                  	mov [ems_first_ovl],ax	; save as first used overlay page
   914                                  	add [ems_first_avail],di	; bump up first available page past those used by overlay file
   915                                  	mov byte [is_emsxms_ovl],1		; set overlay file in EMS/XMS flag
   916                                  
   917                                  ; rewind to start of file
   918                                  	mov bx,[ovl_handle]
   919                                  	xor cx,cx
   920                                  	mov dx,cx				; zero file offset
   921                                  	mov ax,4200h			; move file pointer, absolute offset
   922                                  	int 21h
   923                                  	call	restore_ems_map
   924                                  
   925                                  ; read overlay file into EMS
   926                                  	push	WORD [ems_currmap]	; save current logical state of physical page 0
   927                                  	mov si,[ems_first_ovl]	; si holds first overlay page
   928                                  
   929                                  eos_readloop:
   930                                  	xor al,al
   931                                  	mov bx,si
   932                                  	call	map_ems_page
   933                                  	mov bx,[ovl_handle]
   934                                  	mov cx,16384			; read 16K block
   935                                  	xor dx,dx
   936                                  	push	ds				; save critical register
   937                                  	mov ds,[ems_base]			; ds:dx -> read buffer, EMS physical page 0
   938                                  
   939                                  	call	read_to_ems
   940                                  
   941                                  	pop ds					; restore ds -> warplink data
   942                                  
   943                                  	inc si					; bump to next overlay page
   944                                  	dec di					; drop count of pages to read
   945                                  	jne eos_readloop		; not done yet
   946                                  
   947                                  ; restore previous logical state of physical page 0
   948                                  	xor al,al
   949                                  	pop bx
   950                                  	call	map_ems_page
   951                                  	ret
   952                                  
   953                                  eos_doserr:
   954                                  	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
   955                                  	jmp NEAR PTR dos_error	; error opening file
   956                                  
   957                                  eos_usexms:
   958                                  	mov dx,cx				; get blocks to allocate in K
   959                                  	mov ah,9				; allocate extended memory block
   960                                  	call	far [xms_addr]
   961                                  	call	check_xms_error	; see if error occurred
   962                                  	mov [xms_ovl_handle],dx	; save xms handle
   963                                  	mov [ovl_empb.es_dest_handle],dx	; save in parameter block
   964                                  
   965                                  	mov bx,[ovl_handle]
   966                                  	xor cx,cx
   967                                  	mov dx,cx				; zero file offset
   968                                  	mov ax,4200h			; move file pointer, absolute offset
   969                                  	int 21h
   970                                  	call	restore_ems_map
   971                                  
   972                                  	xor ax,ax
   973                                  	mov WORD PTR [ovl_empb.es_dest_offset],ax	; zero init the XMS offset in parameter block
   974                                  	mov WORD PTR [ovl_empb.es_dest_offset+2],ax
   975                                  	mov WORD PTR [ovl_empb.es_len+2],ax	; zero high word of block length
   976                                  	mov [ovl_empb.es_src_handle],ax	; zero handle (conventional memory source)
   977                                  	mov WORD PTR [ovl_empb.es_src_offset],ax	; zero offset
   978                                  
   979                                  	inc al
   980                                  	mov [is_emsxms_ovl],al	; set overlay file in EMS/XMS flag
   981                                  	mov [ovl_in_xms],al		; set overlay file in XMS only flag
   982                                  
   983                                  	mov ax,16384
   984                                  	mov WORD PTR [ovl_empb.es_len],ax	; length of block to transfer low word
   985                                  	mov ax,[ems_trans_block]
   986                                  	mov WORD PTR [ovl_empb.es_src_offset+2],ax	; source segment
   987                                  
   988                                  eos_xmsread:
   989                                  	mov bx,[ovl_handle]
   990                                  	mov cx,16384			; read 16K block
   991                                  	xor dx,dx
   992                                  	push	ds				; save critical register
   993                                  	mov ds,[ems_trans_block]	; ds:dx -> read buffer
   994                                  	mov ah,3fh				; read file
   995                                  	int 21h
   996                                  	pop ds					; restore ds -> warplink data
   997                                  	call	restore_ems_map
   998                                  	jc  eos_doserr			; error reading file
   999                                  
  1000                                  ; read from file, transfer to XMS
  1001                                  	mov ah,0bh				; move extend memory block
  1002                                  	mov si,OFFSET ovl_empb wrt DGROUP	; ds:si -> parameter block
  1003                                  	call	far [xms_addr]
  1004                                  	call	check_xms_error	; see if error occurred
  1005                                  
  1006                                  	add WORD [ovl_empb.es_dest_offset],16384	; bump dword offset in XMS
  1007                                  	adc WORD [ovl_empb.es_dest_offset+2],0	; carry to high word
  1008                                  
  1009                                  	dec di					; drop count of pages to read
  1010                                  	jne eos_xmsread			; not done yet
  1011                                  
  1012                                  	ret
  1013                                  
  1014                                  ems_ovl_setup   ENDP
  1015                                  
  1016                                  END COMMENT #
  1017                                  %endif
  1018                                  
  1019                                  ;*****************************
  1020                                  ;* WRITE_ZERO_TO_OVL         *
  1021                                  ;*****************************
  1022                                  
  1023                                  ; write di zero bytes to overlay file
  1024                                  ; upon entry bx holds file handle
  1025                                  ; destroys ax,cx,di
  1026                                  
  1027                                  write_zero_to_ovl   PROC
  1028                                  
  1029                                  zero_loop:
  1030 00000434 89F9                    	mov cx,di
  1031 00000436 3B0E[2200]              	cmp cx,[ovl_zeroblk_size]	; only write up to ovl_zeroblk_size bytes each pass thru loop
  1032 0000043A 7604                    	jbe wz_2				; ovl_zeroblk_size bytes or less to write
  1033 0000043C 8B0E[2200]              	mov cx,[ovl_zeroblk_size]
  1034                                  
  1035                                  wz_2:
  1036 00000440 1E                      	push	ds
  1037 00000441 31D2                    	xor dx,dx
  1038 00000443 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay stashed in EMS/XMS
  1039 00000448 8E1E[2000]              	mov ds,[ovl_zeroblk_ptr]	; ds:dx -> zero'd block, KEEP FLAGS
  1040 0000044C 7405                    	je  wz_noems			; overlay not stashed in EMS/XMS
  1041 0000044E E8050C                  	call	ems_ovl_write	; write to overlay in EMS
  1042 00000451 EB10                    	jmp	SHORT wz_3
  1043                                  
  1044                                  wz_noems:
  1045 00000453 B440                    	mov ah,40h				; write to file
  1046 00000455 CD21                    	int 21h
  1047 00000457 E8(0000)                	call	restore_ems_map
  1048 0000045A 720D                    	jc	wz_error			; error occurred
  1049 0000045C 39C8                    	cmp ax, cx
  1050 0000045E B82700                  	mov ax, 27h			; insufficient disk space error
  1051 00000461 7506                    	jne wz_error
  1052                                  
  1053                                  wz_3:
  1054 00000463 1F                      	pop ds
  1055                                  
  1056 00000464 29CF                    	sub di,cx				; subtract number of bytes written this loop pass
  1057 00000466 75CC                    	jne zero_loop			; more bytes to write, loop back
  1058 00000468 C3                      	ret
  1059                                  
  1060                                  ; error occurred writing file
  1061                                  wz_error:
  1062 00000469 BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
  1063 0000046C E9(0000)                	jmp NEAR PTR dos_error	; error opening file
  1064                                  
  1065                                  write_zero_to_ovl   ENDP
  1066                                  
  1067                                  ;*****************************
  1068                                  ;* EMS_OVL_SETUP             *
  1069                                  ;*****************************
  1070                                  
  1071                                  ; setup EMS or XMS to hold overlay file if it fits
  1072                                  ; destroys ax,bx,cx,dx,si,di
  1073                                  
  1074                                  ems_ovl_setup   PROC
  1075 0000046F 803E[0000]00            	cmp byte [is_xms],0			; see if XMS used
  1076 00000474 7508                    	jne eos_chksize			; yes
  1077 00000476 803E[0000]00            	cmp byte [is_no_ems],0			; see if EMS used
  1078 0000047B 7401                    	je  eos_chksize			; yes
  1079 0000047D C3                      	ret
  1080                                  
  1081                                  eos_chksize:
  1082 0000047E A1[1800]                	mov ax,WORD PTR [ovl_file_size]	; get overlay file size in dx:ax
  1083 00000481 8B16[1A00]              	mov dx,WORD PTR [ovl_file_size+2]
  1084 00000485 05FF3F                  	add ax,16383			; round up to nearest 16K boundary
  1085 00000488 83D200                  	adc dx,0				; carry to high word
  1086 0000048B E89500                  	call	convert_to_page	; convert bytes in dx:ax to 16K blocks in ax
  1087                                  
  1088                                  ; check if enough XMS to save overlay file, priority over EMS
  1089 0000048E 803E[0000]00            	cmp byte [is_xms],0			; see if XMS used
  1090 00000493 743A                    	je  eos_chkems			; no
  1091 00000495 89C7                    	mov di,ax				; save 16K block count in di
  1092 00000497 D1E0                    	shl ax,1				; *2
  1093 00000499 D1E0                    	shl ax,1				; *4
  1094 0000049B D1E0                    	shl ax,1				; *8
  1095 0000049D D1E0                    	shl ax,1				; *16, ax holds 1K block count
  1096 0000049F 89C1                    	mov cx,ax				; save 1K block count
  1097 000004A1 B408                    	mov ah,8				; query free extended memory
  1098 000004A3 FF1E[0000]              	call	far [xms_addr]
  1099 000004A7 E8(0000)                	call	check_xms_error	; see if error occurred
  1100 000004AA 39C8                    	cmp ax,cx				; see if largest free block meets 1K block count
  1101 000004AC 7218                    	jb  eos_noxms			; no
  1102                                  
  1103 000004AE 89CA                    	mov dx,cx				; get blocks to allocate in K
  1104 000004B0 B409                    	mov ah,9				; allocate extended memory block
  1105 000004B2 FF1E[0000]              	call	far [xms_addr]
  1106 000004B6 E8(0000)                	call	check_xms_error	; see if error occurred
  1107 000004B9 8916[1C00]              	mov [xms_ovl_handle],dx	; save xms handle
  1108                                  
  1109                                  ; successful allocation for overlay file stashing
  1110 000004BD B001                    	mov	al,1
  1111 000004BF A2[0000]                	mov [is_emsxms_ovl],al	; set overlay file in EMS/XMS flag
  1112 000004C2 A2[0200]                	mov [ovl_in_xms],al		; set overlay file in XMS only flag
  1113                                  
  1114                                  eos_ret:
  1115 000004C5 C3                      	ret
  1116                                  
  1117                                  ; not enough XMS to stuff overlay file in it, try EMS
  1118                                  eos_noxms:
  1119 000004C6 803E[0000]00            	cmp byte [is_no_ems],0			; see if EMS used
  1120 000004CB 75F8                    	jne eos_ret				; no
  1121 000004CD 89F8                    	mov ax,di				; get 16K block count back in ax
  1122                                  
  1123                                  eos_chkems:
  1124 000004CF 3B06[0000]              	cmp ax,[ems_page_avail]	; see if enough pages are available to hold overlay file
  1125 000004D3 770B                    	ja	eos_chkflush		; no, see if flushing will work
  1126                                  
  1127                                  ; enough pages to hold overlay, now see if enough pages for maximum temp file
  1128                                  ; (640K) or 40 pages, otherwise flush
  1129 000004D5 8B1E[0000]              	mov	bx,[ems_page_avail]
  1130 000004D9 29C3                    	sub	bx,ax
  1131 000004DB 83FB28                  	cmp	bx,40				; see if 40 pages left over
  1132 000004DE 732D                    	jae	eos_emsok			; yes
  1133                                  
  1134                                  ; not enough ems to hold overlay file+40 pages for temp file if needed,
  1135                                  ; check if total ems pages allocated-4
  1136                                  ; is enough (if you flush the modules stashed in EMS)
  1137                                  eos_chkflush:
  1138 000004E0 8B3E[0000]              	mov di,[ems_pagecount]	; get total ems pages
  1139 000004E4 83EF04                  	sub di,4				; subtract amount used for file i/o buffer
  1140 000004E7 39F8                    	cmp ax,di				; see if enough total ems pages allocated to hold overlay file
  1141 000004E9 77DA                    	ja  eos_ret				; no
  1142 000004EB C606[0000]01            	mov byte [ems_pages_flushed],1	; set pages flushed flag
  1143 000004F0 C706[0000]0400          	mov word [ems_first_avail],4	; reset first available page flag
  1144 000004F6 893E[0000]              	mov [ems_page_avail],di	; adjust pages available back to pre-module stashed status
  1145 000004FA 89C7                    	mov di,ax				; save overlay file pages
  1146 000004FC 31C0                    	xor ax,ax				; al holds physical page
  1147 000004FE 89C3                    	mov bx,ax				; bx holds logical page
  1148 00000500 B90400                  	mov cx,4				; update all 4 pages in ems page frame
  1149                                  
  1150                                  eos_mapin:
  1151 00000503 E8(0000)                	call	map_ems_page	; map 0->0, 1->1, 2->2, 3->3
  1152 00000506 43                      	inc bx					; bump logical page
  1153 00000507 89D8                    	mov ax,bx				; bump physical page
  1154 00000509 E2F8                    	loop    eos_mapin		; loop until map in complete
  1155 0000050B 89F8                    	mov ax,di				; ax holds overlay file pages
  1156                                  
  1157                                  eos_emsok:
  1158 0000050D 2906[0000]              	sub [ems_page_avail],ax	; subtract off pages used by overlay file
  1159 00000511 89C7                    	mov di,ax				; save overlay page count
  1160 00000513 A1[0000]                	mov ax,[ems_first_avail]	; get first available page
  1161 00000516 A3[1A00]                	mov [ems_first_ovl],ax	; save as first used overlay page
  1162 00000519 013E[0000]              	add [ems_first_avail],di	; bump up first available page past those used by overlay file
  1163 0000051D C606[0000]01            	mov byte [is_emsxms_ovl],1		; set overlay file in EMS/XMS flag
  1164 00000522 C3                      	ret
  1165                                  ems_ovl_setup   ENDP
  1166                                  
  1167                                  ;*****************************
  1168                                  ;* CONVERT_TO_PAGE           *
  1169                                  ;*****************************
  1170                                  
  1171                                  ; convert bytes in dx:ax to 16K blocks in ax
  1172                                  ; destroys ax,dx
  1173                                  
  1174                                  convert_to_page PROC
  1175 00000523 88E0                    	mov al,ah
  1176 00000525 88D4                    	mov ah,dl
  1177 00000527 88F2                    	mov dl,dh
  1178 00000529 30F6                    	xor dh,dh				; register moves perform /256
  1179 0000052B D1EA                    	shr dx,1
  1180 0000052D D1D8                    	rcr ax,1				; /512
  1181 0000052F D1EA                    	shr dx,1
  1182 00000531 D1D8                    	rcr ax,1				; /1024
  1183 00000533 D1EA                    	shr dx,1
  1184 00000535 D1D8                    	rcr ax,1				; /2048
  1185 00000537 D1EA                    	shr dx,1
  1186 00000539 D1D8                    	rcr ax,1				; /4096
  1187 0000053B D1EA                    	shr dx,1
  1188 0000053D D1D8                    	rcr ax,1				; /8192
  1189 0000053F D1EA                    	shr dx,1
  1190 00000541 D1D8                    	rcr ax,1				; /16384, assume dx==0 (no 1G overlay files, pretty safe)
  1191 00000543 C3                      	ret
  1192                                  convert_to_page ENDP
  1193                                  
  1194                                  ;*****************************
  1195                                  ;* CALC_SEG_VALUE            *
  1196                                  ;*****************************
  1197                                  
  1198                                  ; calculates segment value from segdef segment passed in ax
  1199                                  ; returns value in ax
  1200                                  ; destroys ax,cx,es
  1201                                  
  1202                                  calc_seg_value  PROC
  1203 00000544 8EC0                    	mov es,ax				; es -> segdef entry
  1204 00000546 26A10200                	mov ax,[es:2]			; get low word of offset
  1205 0000054A 268B0E0400              	mov cx,[es:4]			; get high word of offset
  1206 0000054F D1E9                    	shr cx,1				; convert to paragraphs
  1207 00000551 D1D8                    	rcr ax,1
  1208 00000553 D1E9                    	shr cx,1
  1209 00000555 D1D8                    	rcr ax,1
  1210 00000557 D1E9                    	shr cx,1
  1211 00000559 D1D8                    	rcr ax,1
  1212 0000055B D1E9                    	shr cx,1
  1213 0000055D D1D8                    	rcr ax,1				; ax holds segment value
  1214 0000055F C3                      	ret
  1215                                  calc_seg_value  ENDP
  1216                                  
  1217                                  ;*****************************
  1218                                  ;* WRITE_VECTORS             *
  1219                                  ;*****************************
  1220                                  
  1221                                  ; write overlay vectors in appropriate segments and lookup table vector values
  1222                                  ; destroys ax,bx,cx,dx,di,si,es
  1223                                  
  1224                                  write_vectors   PROC
  1225 00000560 B8FFFF                  	mov ax,0ffffh
  1226 00000563 A3[0000]                	mov [buffer_end],ax		; set buffer end so that writes from warplink data will never trip buffer wrap code
  1227                                  
  1228                                  ; calculate overlaid public lookup table segment for later use
  1229 00000566 A1[0000]                	mov ax,[lookup_tbl_segdef]
  1230 00000569 E8D8FF                  	call	calc_seg_value
  1231 0000056C A3[1000]                	mov [lookup_segment],ax
  1232                                  
  1233                                  ; calculate overlay public indirect call table segment
  1234 0000056F A1[0000]                	mov ax,[ind_tbl_segdef]
  1235 00000572 E8CFFF                  	call	calc_seg_value
  1236 00000575 A3[1200]                	mov [ind_segment],ax
  1237                                  
  1238                                  ; calculate segment call table segment
  1239 00000578 A1[0000]                	mov ax,[segcall_tbl_segdef]
  1240 0000057B E8C6FF                  	call	calc_seg_value
  1241 0000057E A3[1400]                	mov [segcall_segment],ax
  1242                                  
  1243                                  ; setup the constant vectors to and from overlay manager in vector byte tables
  1244 00000581 E81B03                  	call	set_vector_bytes
  1245                                  
  1246                                  ; Step through all segment entries in overlaid public table.
  1247                                  ; If overlay class, write near and shared vector values at start of segment,
  1248                                  ; public vector values to other segments at end of segment.
  1249                                  ; Update vector written bit for the segment.
  1250                                  
  1251 00000584 A1[0000]                	mov ax,[first_ovlpubblk_ptr]	; get first allocate overlaid public block
  1252 00000587 BB0200                  	mov bx,2				; init block position
  1253 0000058A 8EC0                    	mov es,ax				; es -> public block
  1254                                  
  1255                                  ; no more overlaid publics for this segment, move to next, if any
  1256                                  wv_next_seg:
  1257 0000058C 81FBF703                	cmp bx,OVLPUB_BLK_BYSIZE-9	; see if at end of block for possible trailing invalid publics
  1258 00000590 720E                    	jb  wv_1				; no
  1259 00000592 268E060000              	mov es,[es:0]			; get pointer to next block in ax
  1260 00000597 BB0200                  	mov bx,2				; init block position
  1261 0000059A 8CC0                    	mov ax,es
  1262 0000059C 09C0                    	or  ax,ax				; make sure haven't shot past last block    
  1263 0000059E 7429                    	je  wv_to_chk_segdefs	; past last block, all done
  1264                                  
  1265                                  wv_1:
  1266 000005A0 268A07                  	mov al,[es:bx]			; get flag byte
  1267 000005A3 08C0                    	or  al,al				; see if zero (trailing invalid public declaration bytes)
  1268 000005A5 7514                    	jne wv_1a				; no
  1269                                  
  1270 000005A7 83C303                  	add bx,3				; move to next position in block
  1271 000005AA 8CC0                    	mov ax,es
  1272 000005AC 3B06[0000]              	cmp ax,[alloc_ovlpubblk_ptr]	; see if on last block
  1273 000005B0 75DA                    	jne wv_next_seg			; no, keep looking for segment partition info
  1274 000005B2 3B1E[0000]              	cmp bx,[ovlpubblk_pos]	; see if at last position
  1275 000005B6 72D4                    	jb  wv_next_seg			; no
  1276 000005B8 E99E00                  	jmp NEAR PTR wv_chk_segdefs	; yes, done
  1277                                  
  1278                                  wv_1a:
  1279 000005BB 8CC0                    	mov ax,es
  1280 000005BD 3B06[0000]              	cmp ax,[alloc_ovlpubblk_ptr]	; see if on last block
  1281 000005C1 7509                    	jne wv_more_segs		; no
  1282 000005C3 3B1E[0000]              	cmp bx,[ovlpubblk_pos]	; see if at last position
  1283 000005C7 7203                    	jb  wv_more_segs		; no
  1284                                  
  1285                                  wv_to_chk_segdefs:
  1286 000005C9 E98D00                  	jmp NEAR PTR wv_chk_segdefs	; yes, done
  1287                                  
  1288                                  ; check if room in block for reading in next segment partition info
  1289                                  wv_more_segs:
  1290 000005CC 81FBF703                	cmp bx,OVLPUB_BLK_BYSIZE-9	; see if at end of block
  1291 000005D0 7208                    	jb  wv_get_seg			; no
  1292 000005D2 268E060000              	mov es,[es:0]			; get pointer to next block in ax
  1293 000005D7 BB0200                  	mov bx,2				; init block position
  1294                                  
  1295                                  wv_get_seg:
  1296 000005DA 43                      	inc bx
  1297 000005DB 268B17                  	mov dx,[es:bx]			; get segment partition entry segment in dx
  1298 000005DE 268B4F02                	mov cx,[es:bx+2]		; get total overlaid references in cx
  1299 000005E2 09D2                    	or  dx,dx				; see if nonzero segment partition entry
  1300 000005E4 7525                    	jne wv_ovl_class		; yes
  1301                                  
  1302                                  ; zero segment partition entry, this is an indirect call references entry
  1303 000005E6 83C308                  	add bx,8				; scan past info to first overlaid public
  1304 000005E9 E3A1                    	jcxz    wv_next_seg		; no references
  1305                                  
  1306                                  wv_nonovl_loop:
  1307 000005EB 81FBFD03                	cmp bx,OVLPUB_BLK_BYSIZE-3	; see if at end of block, no room for public declaration entry info
  1308 000005EF 7208                    	jb  wv_nonovl_2			; no
  1309 000005F1 268E060000              	mov es,[es:0]			; get pointer to next block in ax
  1310 000005F6 BB0200                  	mov bx,2				; init block position
  1311                                  
  1312                                  wv_nonovl_2:
  1313 000005F9 268A07                  	mov al,[es:bx]			; get overlaid public flag byte
  1314 000005FC 2480                    	and al,80h				; see if still valid
  1315 000005FE 7404                    	je  wv_nonovl_next		; no
  1316                                  
  1317 00000600 E89401                  	call	write_lookup_vectors	; write lookup vector for indirectly far referenced public
  1318 00000603 49                      	dec cx					; drop count of overlaid publics
  1319                                  
  1320                                  wv_nonovl_next:
  1321 00000604 83C303                  	add bx,3				; move to next overlaid public entry
  1322                                  
  1323                                  to_wv_next_seg:
  1324 00000607 E383                    	jcxz    wv_next_seg		; no more overlaid publics
  1325 00000609 EBE0                    	jmp SHORT wv_nonovl_loop	; loop back for next entry
  1326                                  
  1327                                  wv_ovl_class:
  1328 0000060B 268B4706                	mov ax,[es:bx+6]		; get previous vector bytes count
  1329 0000060F A3[1600]                	mov [prev_vect_bytes],ax	; save to memory variable
  1330 00000612 83C308                  	add bx,8				; scan past info to first overlaid public
  1331 00000615 E81B03                  	call	write_start_vectors
  1332 00000618 E3ED                    	jcxz    to_wv_next_seg	; no end vectors to write
  1333                                  
  1334                                  ;12/21/90, subtract off far vector count from total overlaid reference in cx
  1335 0000061A 89C8                    	mov ax,cx
  1336 0000061C 262B47FC                	sub ax,[es:bx-4]
  1337 00000620 A3[0E00]                	mov [total_ref],ax		; save total overlaid reference for NEARS to memory variable
  1338                                  
  1339 00000623 31FF                    	xor di,di				; di holds current overlaid public count, relative 0
  1340                                  
  1341                                  wv_get_pubs:
  1342 00000625 81FBFD03                	cmp bx,OVLPUB_BLK_BYSIZE-3	; see if at end of block, no room for public declaration entry info
  1343 00000629 7208                    	jb  wv_2				; no
  1344 0000062B 268E060000              	mov es,[es:0]			; get pointer to next block in ax
  1345 00000630 BB0200                  	mov bx,2				; init block position
  1346                                  
  1347                                  wv_2:
  1348 00000633 268A07                  	mov al,[es:bx]			; get overlaid public flag byte
  1349 00000636 24C0                    	and al,0c0h				; see if still valid
  1350 00000638 7415                    	je  wv_next_pub			; no, try next
  1351                                  
  1352 0000063A E8BC03                  	call	write_end_vectors
  1353                                  
  1354                                  wv_2a:
  1355 0000063D E85701                  	call	write_lookup_vectors	; write vector values in lookup table
  1356                                  
  1357                                  ; decrement the value in cx for each near and far bit set
  1358 00000640 268A07                  	mov al,[es:bx]
  1359 00000643 24C0                    	and al,0c0h				; get near and far flag bits
  1360 00000645 A880                    	test	al,80h			; see if far bit set
  1361 00000647 7401                    	je  wv_near_bit			; no
  1362                                  
  1363 00000649 49                      	dec cx
  1364                                  
  1365                                  wv_near_bit:
  1366 0000064A 2440                    	and al,40h				; see if near bit set
  1367 0000064C 7401                    	je  wv_next_pub			; no
  1368 0000064E 49                      	dec cx
  1369                                  
  1370                                  wv_next_pub:
  1371 0000064F 83C303                  	add bx,3				; move to next overlaid public entry
  1372 00000652 09C9                    	or  cx,cx
  1373 00000654 75CF                    	jne wv_get_pubs			; more overlaid publics, get them
  1374 00000656 E933FF                  	jmp NEAR PTR wv_next_seg	; no overlaid publics left
  1375                                  
  1376                                  ; step through all segdef entries, and overlaid segment partition entries
  1377                                  ; if overlay class and vector written bit was not set, write near vector values
  1378                                  ; also, write relocation entry for near vectors to overlay manager
  1379                                  wv_chk_segdefs:
  1380 00000659 A1[0000]                	mov ax,[first_segdefblk_ptr]	; get first segdef block pointer
  1381                                  
  1382                                  wv_seg_blkloop:
  1383 0000065C 09C0                    	or  ax,ax				; see if another block
  1384 0000065E 7502                    	jne wv_moreblk			; yes
  1385 00000660 EB4C                    	jmp NEAR PTR wv_ret		; no
  1386                                  
  1387                                  wv_moreblk:
  1388 00000662 8EC0                    	mov es,ax				; es -> segdef block
  1389 00000664 8CC6                    	mov si,es				; keep -> segdef block
  1390                                  
  1391 00000666 268B0E0000              	mov cx,[es:0]			; get count of entries in block
  1392 0000066B 40                      	inc ax					; bump to first segdef entry in block
  1393                                  
  1394                                  wv_seg_entloop:
  1395 0000066C 8EC0                    	mov es,ax				; es -> segdef entry
  1396 0000066E 89C7                    	mov di,ax				; save -> segdef entry in di
  1397 00000670 26A01C00                	mov al,[es:28]
  1398 00000674 A801                    	test	al,1			; see if overlay class
  1399 00000676 7427                    	je  wv_next_segdef		; no
  1400                                  
  1401 00000678 26A11600                	mov ax,[es:22]			; get pointer to first segment partition entry
  1402                                  
  1403                                  wv_loop:
  1404 0000067C 09C0                    	or  ax,ax				; see if valid segment partition pointer
  1405 0000067E 741F                    	je  wv_next_segdef		; no, no more segment partition entries for this segdef
  1406 00000680 8EC0                    	mov es,ax				; es -> segment partition entry
  1407 00000682 26F6060F0080            	test	BYTE PTR [es:15],80h	; see if overlaid segment
  1408 00000688 7408                    	je  wv_3				; no
  1409                                  
  1410                                  ; overlaid segment
  1411 0000068A 26F6060F0010            	test	BYTE PTR [es:15],10h	; see if near vectors were written for segment
  1412 00000690 7507                    	jne wv_next_segpart		; yes
  1413                                  
  1414                                  ; either overlaid segment that hasn't had near vectors or non-overlaid segment
  1415                                  ; if non-overlaid segment, write_start_vectors will weed out those that
  1416                                  ; already have the near vectors written, so don't bother to test for it
  1417                                  wv_3:
  1418 00000692 8CC2                    	mov dx,es				; get segment partition entry in dx for write_start_vectors
  1419 00000694 56                      	push	si				; save critical register
  1420 00000695 E89B02                  	call	write_start_vectors
  1421 00000698 5E                      	pop si					; restore critical register
  1422                                  
  1423                                  wv_next_segpart:
  1424 00000699 26A10200                	mov ax,[es:2]			; get pointer to next segment partition entry, if any
  1425 0000069D EBDD                    	jmp SHORT wv_loop		; loop back until all entries for this segdef exhausted
  1426                                  
  1427                                  wv_next_segdef:
  1428 0000069F 89F8                    	mov ax,di				; ax -> old segdef entry
  1429 000006A1 83C002                  	add ax,2				; move to next segdef entry in block
  1430 000006A4 E2C6                    	loop    wv_seg_entloop	; loop through all entries in block
  1431                                  
  1432 000006A6 8EC6                    	mov es,si				; restore es -> segdef block
  1433 000006A8 26A10200                	mov ax,[es:2]			; get pointer to next block, if any
  1434 000006AC EBAE                    	jmp wv_seg_blkloop	; loop for next block
  1435                                  
  1436                                  wv_ret:
  1437 000006AE C706[0000]0000          	mov word [ovl_code_id],0		; zero overlay identifer
  1438 000006B4 E89B01                  	call	flush_lookup	; flush any remaining entries in lookup array to disk
  1439 000006B7 E80400                  	call	write_ind_call	; write indirect call table segment
  1440 000006BA E88800                  	call	write_seg_call	; write segment call table for segment fixups
  1441 000006BD C3                      	ret
  1442                                  write_vectors   ENDP
  1443                                  
  1444                                  ;*****************************
  1445                                  ;* WRITE_IND_CALL            *
  1446                                  ;*****************************
  1447                                  
  1448                                  ; write indirect call table to $$_ovl_ind_call_table segment
  1449                                  ; at offset zero is the far jump to to-root entry in the overlay manager,
  1450                                  ; and the far jump to to-overlay entry in the overlay manager,
  1451                                  ; destroys ax,bx,cx,dx,di,si,es
  1452                                  
  1453                                  write_ind_call  PROC
  1454                                  
  1455                                  ; get offset of indirect call segment in data_offset
  1456 000006BE A1[0000]                	mov ax,[ind_tbl_segdef]	; get segdef segment of indirect call table
  1457 000006C1 8EC0                    	mov es,ax				; es -> segdef entry
  1458 000006C3 26C4060200              	les ax,[es:2]			; get low/high word of offset in es:ax
  1459 000006C8 A3[0000]                	mov WORD PTR [data_offset],ax
  1460 000006CB 8CC0                    	mov ax,es
  1461 000006CD A3[0200]                	mov WORD PTR [data_offset+2],ax
  1462                                  
  1463                                  ; get segment of indirect call segment in data_segment variable for make_reloc_entry
  1464 000006D0 A1[1200]                	mov ax,[ind_segment]
  1465 000006D3 A3[0000]                	mov [data_segment],ax
  1466                                  
  1467 000006D6 FF36[0000]              	push	word [ovl_pubcount]	; save number of near calls to write on the stack
  1468 000006DA BE[5100]                	mov si,OFFSET ind_vector_bytes wrt DGROUP	; es:si -> bytes to write
  1469                                  
  1470                                  ; code shared with segment call via segment fixup routine
  1471                                  write_shared:
  1472 000006DD 8CD8                    	mov ax,ds
  1473 000006DF 8EC0                    	mov es,ax
  1474 000006E1 B90500                  	mov cx,5				; write 1 vector to overlay manager
  1475 000006E4 E8(0000)                	call	write_bytes		; write the bytes
  1476                                  
  1477 000006E7 59                      	pop cx					; write as many near calls as are in cx
  1478                                  
  1479 000006E8 BA0300                  	mov dx,3				; fixup location in segment for root to overlay
  1480 000006EB E8(0000)                	call	make_reloc_entry
  1481                                  
  1482 000006EE 8306[0000]10            	add WORD [data_offset],10h	; adjust past paragraph of vectors
  1483 000006F3 8316[0200]00            	adc WORD [data_offset+2],0	; carry to high word
  1484 000006F8 BFEDFF                  	mov di,0ffedh			; initialize CALL disp16 offset
  1485                                  
  1486                                  ind_loop2:
  1487 000006FB BB[0000]                	mov bx,OFFSET ind_tbl_array wrt DGROUP	; init table position
  1488                                  
  1489                                  write_ind_loop:
  1490 000006FE E318                    	jcxz    write_ind_out	; done, pass any remaining calls to write_bytes routine
  1491                                  
  1492 00000700 C607E8                  	mov BYTE PTR [bx],0e8h	; CALL disp16 opcode
  1493 00000703 897F01                  	mov [bx+1],di			; save computed offset
  1494 00000706 83EF03                  	sub di,3				; adjust di for next call
  1495                                  
  1496 00000709 49                      	dec cx					; drop count of calls to write
  1497 0000070A 83C303                  	add bx,3				; adjust to new near call position
  1498 0000070D 81FB[FD07]              	cmp bx,OFFSET ind_tbl_array+800h-3 wrt DGROUP	; see if table overflowed, time to write to disk
  1499 00000711 72EB                    	jb  write_ind_loop		; no, keep writing call bytes to table
  1500 00000713 E80200                  	call	write_ind_out	; sneaky call that shares procedure return with subprocedure return
  1501 00000716 EBE3                    	jmp SHORT ind_loop2		; loop back for next set of calls, reinit'ing bx
  1502                                  
  1503                                  ; write the indirect call tables to the write_bytes routine
  1504                                  write_ind_out:
  1505 00000718 51                      	push	cx				; save critical register
  1506 00000719 57                      	push	di
  1507 0000071A 81FB[0000]              	cmp bx,OFFSET ind_tbl_array wrt DGROUP	; see if any entries to write
  1508 0000071E 7622                    	jbe wic_ret				; no
  1509 00000720 89D9                    	mov cx,bx
  1510 00000722 BE[0000]                	mov si,OFFSET ind_tbl_array wrt DGROUP	; es:si -> bytes to write
  1511 00000725 29F1                    	sub cx,si				; get number of bytes to write
  1512 00000727 89CA                    	mov dx,cx				; save in dx
  1513                                  
  1514 00000729 FF36[0000]              	push	word [ovl_code_id]		; save current overlay code identifier
  1515 0000072D 31C0                    	xor ax,ax
  1516 0000072F A3[0000]                	mov [ovl_code_id],ax		; zero for write_bytes routine so writes to root file
  1517 00000732 E8(0000)                	call	write_bytes		; write the bytes
  1518 00000735 8F06[0000]              	pop word [ovl_code_id]			; restore current overlay code identifier
  1519                                  
  1520 00000739 0116[0000]              	add WORD PTR [data_offset],dx	; update data_offset variable for next write
  1521 0000073D 8316[0200]00            	adc WORD [data_offset+2],0	; carry to high word
  1522                                  
  1523                                  wic_ret:
  1524 00000742 5F                      	pop di
  1525 00000743 59                      	pop cx					; restore critical register
  1526 00000744 C3                      	ret
  1527                                  write_ind_call  ENDP
  1528                                  
  1529                                  ;*****************************
  1530                                  ;* WRITE_SEG_CALL            *
  1531                                  ;*****************************
  1532                                  
  1533                                  ; write segment call table to $$_ovl_seg_call_table segment
  1534                                  ; at offset zero is the far jump to segmet call entry in the overlay manager,
  1535                                  ; destroys ax,bx,cx,dx,di,si,es
  1536                                  
  1537                                  write_seg_call  PROC
  1538                                  
  1539                                  ; get offset of indirect call segment in data_offset
  1540 00000745 A1[0000]                	mov ax,[segcall_tbl_segdef]	; get segdef segment of indirect call table
  1541 00000748 8EC0                    	mov es,ax				; es -> segdef entry
  1542 0000074A 26C4060200              	les ax,[es:2]			; get low/high word of offset in es:ax
  1543 0000074F A3[0000]                	mov WORD PTR [data_offset],ax
  1544 00000752 8CC0                    	mov ax,es
  1545 00000754 A3[0200]                	mov WORD PTR [data_offset+2],ax
  1546                                  
  1547                                  ; get segment of segment call segment in data_segment variable for make_reloc_entry
  1548 00000757 A1[1400]                	mov ax,[segcall_segment]
  1549 0000075A A3[0000]                	mov [data_segment],ax
  1550                                  
  1551 0000075D FF36[0000]              	push	word [ovl_count]		; save number of near calls to write on the stack
  1552 00000761 BE[5600]                	mov si,OFFSET segcall_vect_bytes wrt DGROUP	; es:si -> bytes to write
  1553                                  
  1554 00000764 E976FF                  	jmp NEAR PTR write_shared	; jump to code shared with the indirect call segment
  1555                                  
  1556                                  write_seg_call  ENDP
  1557                                  
  1558                                  ;*****************************
  1559                                  ;* WRITE_SEG_REL_ENTRY       *
  1560                                  ;*****************************
  1561                                  
  1562                                  ; write relocation entry in main program for root overlay class segment vectors
  1563                                  ; destroys ax,bx,dx,di
  1564                                  
  1565                                  write_seg_rel_entry PROC
  1566 00000767 26A10200                	mov ax,[es:2]			; get segment offset into data_offset variable for make_reloc_entry proc
  1567 0000076B A3[0000]                	mov WORD PTR [data_offset],ax
  1568 0000076E 268B1E0400              	mov bx,[es:4]			; get high word
  1569 00000773 891E[0200]              	mov WORD PTR [data_offset+2],bx
  1570                                  
  1571                                  ; convert bytes in bx:ax to paragraphs in ax for data_segment variable for make_reloc_entry
  1572 00000777 D1EB                    	shr bx,1
  1573 00000779 D1D8                    	rcr ax,1				; /2
  1574 0000077B D1EB                    	shr bx,1
  1575 0000077D D1D8                    	rcr ax,1				; /4
  1576 0000077F D1EB                    	shr bx,1
  1577 00000781 D1D8                    	rcr ax,1				; /8
  1578 00000783 D1EB                    	shr bx,1
  1579 00000785 D1D8                    	rcr ax,1				; /16
  1580 00000787 A3[0000]                	mov [data_segment],ax
  1581                                  
  1582 0000078A BA1D00                  	mov dx,1dh				; near vector fixup location in segment
  1583 0000078D E8(0000)                	call	make_reloc_entry
  1584 00000790 BA2A00                  	mov dx,2ah				; shared vector fixup location in segment
  1585 00000793 E8(0000)                	call	make_reloc_entry
  1586 00000796 C3                      	ret
  1587                                  write_seg_rel_entry ENDP
  1588                                  
  1589                                  ;*****************************
  1590                                  ;* WRITE_LOOKUP_VECTORS      *
  1591                                  ;*****************************
  1592                                  
  1593                                  ; write offset and segment values for each overlaid public entry
  1594                                  ; at the appropriate place in the $$_ovl_lookup_table segment.
  1595                                  ; offset  == the public declarations offset, plus segment partition offset and
  1596                                  ; master segdef entry normalized offset if the segment partition is not overlaid.
  1597                                  ; segment == the segment partition overlay identifier if overlaid, or
  1598                                  ; the master segdef entry offset (normalized) if not overlaid.
  1599                                  ; upon entry es:bx -> first overlaid public flag byte in overlaid public table
  1600                                  ; dx holds segment partition entry segment
  1601                                  ; destroys ax,si
  1602                                  
  1603                                  write_lookup_vectors    PROC
  1604 00000797 53                      	push	bx				; save critical registers
  1605 00000798 51                      	push	cx
  1606 00000799 52                      	push	dx
  1607 0000079A 06                      	push	es
  1608                                  
  1609 0000079B 268E4701                	mov es,[es:bx+1]		; es -> overlaid public
  1610 0000079F 26F6060F0002            	test	BYTE PTR [es:15],2	; see if vector already written for public
  1611 000007A5 7403                    	je  wlv_1				; no
  1612 000007A7 E9A300                  	jmp NEAR PTR wlv_ret	; yes
  1613                                  
  1614                                  wlv_1:
  1615 000007AA 26800E0F0002            	or  BYTE PTR [es:15],2	; set vector written flag
  1616 000007B0 268B0E0800              	mov cx,[es:8]			; get public offset
  1617 000007B5 268E060000              	mov es,[es:0]			; es -> segment partition entry owning public
  1618 000007BA 268A160F00              	mov dl,[es:15]			; get overlay flag for segment
  1619 000007BF 80E280                  	and dl,80h				; see if segment overlaid
  1620 000007C2 7507                    	jne wlv_2				; yes
  1621                                  
  1622 000007C4 26030E0000              	add cx,[es:0]			; add in segment partition offset
  1623 000007C9 06                      	push	es				; save es -> segment partition entry
  1624 000007CA 07                      	pop es					; restore es -> segment partition entry
  1625                                  
  1626                                  wlv_2:
  1627 000007CB 8B1E[1000]              	mov bx,[lookup_tbl_pos]	; get current position in lookup table
  1628 000007CF 81E3FF07                	and bx,7ffh				; get position in array
  1629 000007D3 81C3[0000]              	add bx,OFFSET lookup_tbl_array wrt DGROUP	; add in array's offset in memory
  1630 000007D7 890F                    	mov [bx],cx				; save offset
  1631 000007D9 83C302                  	add bx,2				; move to segment position in array
  1632 000007DC 80FA80                  	cmp dl,80h				; see if segment if overlaid
  1633 000007DF 7525                    	jne wlv_3				; no
  1634                                  
  1635                                  ; overlaid segment
  1636                                  ; 12/25/90, set flag to indicate overlaid segment (reset bit 6 of byte 6)
  1637                                  ; write offset to near vector value
  1638 000007E1 268B0E0C00              	mov cx,[es:12]			; get segment length
  1639 000007E6 26A10E00                	mov ax,[es:14]			; get vector count
  1640 000007EA 80E407                  	and ah,7				; mask off flag bits (only bit 0-2 used)
  1641 000007ED BA0700                  	mov dx,7				; 7 bytes per vector
  1642 000007F0 F7E2                    	mul dx					; dx:ax holds vector bytes, dx always zero
  1643 000007F2 83C020                  	add ax,20h				; adjust for near/shared vector paragraphs
  1644 000007F5 29C1                    	sub cx,ax				; cx holds near vector offset value
  1645 000007F7 894F02                  	mov [bx+2],cx			; save offset to near vector
  1646 000007FA C747040000              	mov WORD PTR [bx+4],0	; reset root segment bit
  1647 000007FF 268B0E0400              	mov cx,[es:4]			; get overlay identifier
  1648 00000804 EB34                    	jmp SHORT wlv_4			; bypass root segment code
  1649                                  
  1650                                  ; root segment
  1651                                  ; 12/25/90, set flag to indicate root segment (set bit 6 of byte 6)
  1652                                  wlv_3:
  1653 00000806 268E060400              	mov es,[es:4]			; es -> master segdef entry
  1654                                  
  1655                                  ; write offset to near vector value
  1656 0000080B 268B0E0600              	mov cx,[es:6]			; get segment length
  1657 00000810 26A11E00                	mov ax,[es:30]			; get count of vector bytes
  1658 00000814 83C020                  	add ax,20h				; adjust for near/shared vector paragraphs
  1659 00000817 29C1                    	sub cx,ax				; cx holds near vector offset value
  1660 00000819 894F02                  	mov [bx+2],cx			; save offset to near vector
  1661 0000081C C747044000              	mov WORD PTR [bx+4],40h	; set root segment bit
  1662                                  
  1663 00000821 268B0E0200              	mov cx,[es:2]			; cx holds low word of segment offset
  1664 00000826 26A10400                	mov ax,[es:4]			; ax holds high word of segment offset
  1665 0000082A D1E8                    	shr ax,1				; convert to paragraph for segment value
  1666 0000082C D1D9                    	rcr cx,1
  1667 0000082E D1E8                    	shr ax,1
  1668 00000830 D1D9                    	rcr cx,1
  1669 00000832 D1E8                    	shr ax,1
  1670 00000834 D1D9                    	rcr cx,1
  1671 00000836 D1E8                    	shr ax,1
  1672 00000838 D1D9                    	rcr cx,1				; cx holds normalized segment value
  1673                                  
  1674                                  wlv_4:
  1675 0000083A 890F                    	mov [bx],cx				; save segment
  1676                                  
  1677 0000083C A1[1000]                	mov ax,[lookup_tbl_pos]
  1678 0000083F 83C008                  	add ax,8
  1679 00000842 A3[1000]                	mov [lookup_tbl_pos],ax	; bump position to next seg:off pair
  1680 00000845 25FF07                  	and ax,7ffh				; see if at end of array
  1681 00000848 7503                    	jne wlv_ret				; no
  1682 0000084A E80500                  	call	flush_lookup	; flush the previous lookup array to disk
  1683                                  
  1684                                  wlv_ret:
  1685 0000084D 07                      	pop es					; restore critical registers
  1686 0000084E 5A                      	pop dx
  1687 0000084F 59                      	pop cx
  1688 00000850 5B                      	pop bx
  1689 00000851 C3                      	ret
  1690                                  write_lookup_vectors    ENDP
  1691                                  
  1692                                  ;*****************************
  1693                                  ;* FLUSH_LOOKUP              *
  1694                                  ;*****************************
  1695                                  
  1696                                  ; flush lookup array to disk
  1697                                  ; destroys ax,bx,cx,dx,si,es
  1698                                  
  1699                                  flush_lookup    PROC
  1700 00000852 57                      	push	di				; save critical register
  1701 00000853 A1[0000]                	mov ax,[lookup_tbl_segdef]	; get segdef segment of overlay lookup table
  1702 00000856 8EC0                    	mov es,ax				; es -> segdef entry
  1703 00000858 26A10200                	mov ax,[es:2]			; get low word of offset
  1704 0000085C A3[0000]                	mov WORD PTR [data_offset],ax
  1705 0000085F 26A10400                	mov ax,[es:4]			; get high word
  1706 00000863 A3[0200]                	mov WORD PTR [data_offset+2],ax
  1707                                  
  1708 00000866 A1[1000]                	mov ax,[lookup_tbl_pos]
  1709 00000869 89C1                    	mov cx,ax
  1710 0000086B E330                    	jcxz    fl_ret			; no bytes to write
  1711 0000086D 81E1FF07                	and cx,7ffh
  1712 00000871 7503                    	jne fl_1				; not an even 800h byte block to write
  1713 00000873 B90008                  	mov cx,800h				; an even 800h byte block
  1714                                  
  1715                                  fl_1:
  1716 00000876 3D0008                  	cmp ax,800h				; see if previous bytes written
  1717 00000879 760B                    	jbe fl_2				; no, make no adjustment
  1718                                  
  1719 0000087B 29C8                    	sub ax,cx				; ax -> place in lookup table segment to write to
  1720                                  
  1721 0000087D 0106[0000]              	add WORD PTR [data_offset],ax	; adjust offset to proper place in segment
  1722 00000881 8316[0200]00            	adc WORD [data_offset+2],0	; carry to high word
  1723                                  
  1724                                  fl_2:
  1725 00000886 8CD8                    	mov ax,ds
  1726 00000888 8EC0                    	mov es,ax
  1727 0000088A BE[0000]                	mov si,OFFSET lookup_tbl_array wrt DGROUP	; es:si -> bytes to write
  1728                                  
  1729 0000088D FF36[0000]              	push	word [ovl_code_id]		; save current overlay code identifier
  1730 00000891 31C0                    	xor ax,ax
  1731 00000893 A3[0000]                	mov [ovl_code_id],ax		; zero for write_bytes routine so writes to root file
  1732 00000896 E8(0000)                	call	write_bytes
  1733 00000899 8F06[0000]              	pop word [ovl_code_id]			; restore current overlay code identifier
  1734                                  
  1735                                  fl_ret:
  1736 0000089D 5F                      	pop di					; restore critical register
  1737 0000089E C3                      	ret
  1738                                  flush_lookup    ENDP
  1739                                  
  1740                                  ;*****************************
  1741                                  ;* SET_VECTOR_BYTES          *
  1742                                  ;*****************************
  1743                                  
  1744                                  ; setup the constant vectors to and from overlay manager in vector byte tables
  1745                                  ; destroys ax,bx,cx,dx,di,es
  1746                                  
  1747                                  set_vector_bytes    PROC
  1748                                  
  1749 0000089F C606[0000]01            	mov byte [no_match_okay],1		; set flag that no matches in public search are okay
  1750                                  
  1751                                  ; write to_vector_bytes segment:offset
  1752 000008A4 BF[0000]                	mov di,OFFSET vector_text wrt DGROUP
  1753 000008A7 E8(0000)                	call	find_pubdecl_entry	; find the symbol
  1754 000008AA 09C0                    	or  ax,ax				; make sure nonzero
  1755 000008AC 744C                    	je  svb_mgrerr			; not found, assume overlay manager wasn't linked in
  1756                                  
  1757 000008AE E84F00                  	call	get_symbol_segoff
  1758 000008B1 A3[4400]                	mov WORD PTR [to_vector_bytes],ax	; save offset value
  1759 000008B4 8916[4600]              	mov WORD PTR [to_vector_bytes+2],dx	; save segment value
  1760                                  
  1761                                  ; write ret_vector_bytes segment:offset
  1762 000008B8 BF[0E00]                	mov di,OFFSET ret_text wrt DGROUP
  1763 000008BB E8(0000)                	call	find_pubdecl_entry	; find the symbol
  1764 000008BE 09C0                    	or  ax,ax				; make sure nonzero
  1765 000008C0 7438                    	je  svb_mgrerr			; not found, assume overlay manager wasn't linked in
  1766                                  
  1767 000008C2 E83B00                  	call	get_symbol_segoff
  1768 000008C5 A3[3700]                	mov WORD PTR [ret_vector_bytes],ax	; save offset value
  1769 000008C8 8916[3900]              	mov WORD PTR [ret_vector_bytes+2],dx	; save segment value
  1770                                  
  1771                                  ; write to_2o_bytes segment:offset
  1772 000008CC BF[1900]                	mov di,OFFSET ovl_2o_text wrt DGROUP
  1773 000008CF E8(0000)                	call	find_pubdecl_entry	; find the symbol
  1774 000008D2 09C0                    	or  ax,ax				; make sure nonzero
  1775 000008D4 7424                    	je  svb_mgrerr			; not found, assume overlay manager wasn't linked in
  1776                                  
  1777 000008D6 E82700                  	call	get_symbol_segoff
  1778 000008D9 A3[5200]                	mov WORD PTR [to_2o_bytes],ax		; save offset value
  1779 000008DC 8916[5400]              	mov WORD PTR [to_2o_bytes+2],dx	; save segment value
  1780                                  
  1781                                  ; write to_segcall_bytes segment:offset
  1782 000008E0 BF[2D00]                	mov di,OFFSET ovl_segcall_text wrt DGROUP
  1783 000008E3 E8(0000)                	call	find_pubdecl_entry	; find the symbol
  1784 000008E6 09C0                    	or  ax,ax				; make sure nonzero
  1785 000008E8 7410                    	je  svb_mgrerr			; not found, assume overlay manager wasn't linked in
  1786                                  
  1787 000008EA E81300                  	call	get_symbol_segoff
  1788 000008ED A3[5700]                	mov WORD PTR [to_segcall_bytes],ax	; save offset value
  1789 000008F0 8916[5900]              	mov WORD PTR [to_segcall_bytes+2],dx	; save segment value
  1790                                  
  1791 000008F4 C606[0000]00            	mov byte [no_match_okay],0		; done, reset flag so remaining no matches generate internal errors
  1792                                  
  1793 000008F9 C3                      	ret
  1794                                  
  1795                                  ; overlay manager not linked in, fatal error
  1796                                  svb_mgrerr:
  1797 000008FA B84100                  	mov ax,MISSING_OVLMGR_ERR
  1798 000008FD E9(0000)                	jmp NEAR PTR link_error
  1799                                  
  1800                                  set_vector_bytes    ENDP
  1801                                  
  1802                                  ;*****************************
  1803                                  ;* GET_SYMBOL_SEGOFF         *
  1804                                  ;*****************************
  1805                                  
  1806                                  ; return segment:offset of variable in ax:dx
  1807                                  ; upon entry ax -> public declaration entry of symbol
  1808                                  ; destroys ax,bx,cx,dx,es
  1809                                  
  1810                                  get_symbol_segoff   PROC
  1811 00000900 8EC0                    	mov es,ax				; es -> public declaration entry
  1812 00000902 268B1E0800              	mov bx,[es:8]			; get public offset
  1813 00000907 268E060000              	mov es,[es:0]			; es -> segment partition entry
  1814 0000090C 268E060400              	mov es,[es:4]			; es -> master segdef entry
  1815 00000911 268B160200              	mov dx,[es:2]			; get segment offset low word
  1816 00000916 89D0                    	mov ax,dx
  1817 00000918 268B0E0400              	mov cx,[es:4]			; get segment offset high word
  1818 0000091D 83E00F                  	and ax,15				; get leftover bytes from canonical (normalized) segment
  1819 00000920 D1E9                    	shr cx,1				; convert bytes to paragraphs for segment value
  1820 00000922 D1DA                    	rcr dx,1
  1821 00000924 D1E9                    	shr cx,1
  1822 00000926 D1DA                    	rcr dx,1
  1823 00000928 D1E9                    	shr cx,1
  1824 0000092A D1DA                    	rcr dx,1
  1825 0000092C D1E9                    	shr cx,1
  1826 0000092E D1DA                    	rcr dx,1				; dx now holds variable segment value
  1827 00000930 01D8                    	add ax,bx				; ax holds variable offset value
  1828 00000932 C3                      	ret
  1829                                  get_symbol_segoff   ENDP
  1830                                  
  1831                                  ;*****************************
  1832                                  ;* WRITE_START_VECTORS       *
  1833                                  ;*****************************
  1834                                  
  1835                                  ; write the near and shared vectors
  1836                                  ; upon entry dx holds segment partition entry segment
  1837                                  ; destroys ax,si
  1838                                  
  1839                                  write_start_vectors PROC
  1840 00000933 51                      	push	cx				; save critical registers
  1841 00000934 52                      	push	dx
  1842 00000935 57                      	push	di
  1843 00000936 06                      	push	es
  1844 00000937 8EC2                    	mov es,dx				; es -> segment partition entry
  1845 00000939 26A00F00                	mov al,[es:15]			; get overlay flag
  1846 0000093D 2480                    	and al,80h				; see if overlaid
  1847 0000093F 7431                    	je  wsv_not_overlaid	; no
  1848                                  
  1849 00000941 26800E0F0040            	or  BYTE PTR [es:15],40h	; set vector values written flag
  1850 00000947 26A10400                	mov ax,[es:4]			; get overlay identifier
  1851 0000094B A3[0000]                	mov [ovl_code_id],ax		; save to identifier flag
  1852 0000094E A3[3E00]                	mov WORD PTR [source_id_word],ax	; save identifier in source id
  1853                                  
  1854 00000951 268B0E0C00              	mov cx,[es:12]			; get segment length
  1855 00000956 26A10E00                	mov ax,[es:14]			; get vector count
  1856 0000095A 80E407                  	and ah,7				; mask off flag bits (only bit 0-2 used)
  1857 0000095D BA0700                  	mov dx,7				; 7 bytes per vector
  1858 00000960 F7E2                    	mul dx					; dx:ax holds vector bytes, dx always zero
  1859 00000962 83C020                  	add ax,20h				; adjust for near/shared vector paragraphs
  1860 00000965 29C1                    	sub cx,ax				; cx holds near vector offset value
  1861 00000967 890E[0000]              	mov WORD PTR [data_offset],cx	; save offset to near vector
  1862 0000096B 31C0                    	xor ax,ax
  1863 0000096D A3[0200]                	mov WORD PTR [data_offset+2],ax	; zero high word of offset
  1864 00000970 EB66                    	jmp SHORT wsv_shared	; jump to shared portion of code
  1865                                  
  1866                                  wsv_not_overlaid:
  1867 00000972 C706[0000]0000          	mov word [ovl_code_id],0		; zero overlay identifer
  1868 00000978 268E060400              	mov es,[es:4]			; es -> master segdef entry for segment partition
  1869 0000097D B040                    	mov al,40h
  1870 0000097F 2684061C00              	test	[es:28],al		; see if vector values already written
  1871 00000984 756E                    	jne wsv_ret				; yes, don't write them again
  1872 00000986 2608061C00              	or  [es:28],al			; set vector values written flag
  1873 0000098B B080                    	mov al,80h
  1874 0000098D A2[3F00]                	mov BYTE PTR [source_id_word+1],al	; set high bit of source id to indicate call from root
  1875                                  
  1876 00000990 268B160600              	mov dx,[es:6]			; get segment length
  1877 00000995 09D2                    	or  dx,dx				; make sure nonzero length segment
  1878 00000997 745B                    	je  wsv_ret				; zero length
  1879 00000999 26A11E00                	mov ax,[es:30]			; get count of vector bytes
  1880 0000099D 83C020                  	add ax,20h				; adjust for near/shared vector paragraphs
  1881 000009A0 29C2                    	sub dx,ax				; dx holds near vector offset value
  1882 000009A2 89D1                    	mov cx,dx				; save value in cx
  1883 000009A4 26A10200                	mov ax,[es:2]			; get low word of segment offset
  1884 000009A8 01D0                    	add ax,dx				; calculate offset to near vector
  1885 000009AA A3[0000]                	mov WORD PTR [data_offset],ax
  1886 000009AD 268B160400              	mov dx,[es:4]			; get high word of segment offset
  1887 000009B2 83D200                  	adc dx,0				; carry to high word
  1888 000009B5 8916[0200]              	mov WORD PTR [data_offset+2],dx
  1889                                  
  1890                                  ; convert bytes in dx:ax to paragraphs in ax for data_segment variable for make_reloc_entry
  1891 000009B9 D1EA                    	shr dx,1
  1892 000009BB D1D8                    	rcr ax,1				; /2
  1893 000009BD D1EA                    	shr dx,1
  1894 000009BF D1D8                    	rcr ax,1				; /4
  1895 000009C1 D1EA                    	shr dx,1
  1896 000009C3 D1D8                    	rcr ax,1				; /8
  1897 000009C5 D1EA                    	shr dx,1
  1898 000009C7 D1D8                    	rcr ax,1				; /16
  1899 000009C9 A3[0000]                	mov [data_segment],ax
  1900                                  
  1901                                  ; write relocation items for root near/shared vector jumps to overlay manager
  1902 000009CC BA0D00                  	mov dx,0dh				; near vector
  1903 000009CF E8(0000)                	call	make_reloc_entry
  1904 000009D2 BA1A00                  	mov dx,1ah				; shared vector
  1905 000009D5 E8(0000)                	call	make_reloc_entry
  1906                                  
  1907                                  wsv_shared:
  1908                                  ; write the pop/call cs-relative data address, offset to vector in cx
  1909 000009D8 890E[1800]              	mov [nearv_offset],cx		; save near vector offset for write_end_vectors use
  1910 000009DC 83C11C                  	add cx,1ch				; bump offset to cs_relative data address
  1911 000009DF 890E[2F00]              	mov WORD PTR [near_pop],cx	; update pop address
  1912 000009E3 890E[3400]              	mov WORD PTR [near_call],cx	; update call address
  1913                                  
  1914 000009E7 8CD8                    	mov ax,ds
  1915 000009E9 8EC0                    	mov es,ax
  1916 000009EB BE[2C00]                	mov si,OFFSET near_vector_bytes wrt DGROUP	; es:si -> bytes to write
  1917 000009EE B91C00                  	mov cx,28				; write 28 bytes
  1918 000009F1 E8(0000)                	call	write_bytes
  1919                                  
  1920                                  wsv_ret:
  1921 000009F4 07                      	pop es					; restore critical registers
  1922 000009F5 5F                      	pop di
  1923 000009F6 5A                      	pop dx
  1924 000009F7 59                      	pop cx
  1925 000009F8 C3                      	ret
  1926                                  write_start_vectors ENDP
  1927                                  
  1928                                  ;*****************************
  1929                                  ;* WRITE_END_VECTORS         *
  1930                                  ;*****************************
  1931                                  
  1932                                  ; write vectors at end of segment, public vectors
  1933                                  ; upon entry es:bx -> first overlaid public flag byte in overlaid public table
  1934                                  ; cx holds total count of overlaid publics
  1935                                  ; di holds current count of vectored overlaid publics, relative 0
  1936                                  ; dx holds segment partition entry segment
  1937                                  ; updates di
  1938                                  ; destroys ax,si
  1939                                  
  1940                                  write_end_vectors   PROC
  1941 000009F9 53                      	push	bx				; save critical registers
  1942 000009FA 51                      	push	cx
  1943 000009FB 52                      	push	dx
  1944 000009FC 06                      	push	es
  1945                                  
  1946 000009FD 268A0F                  	mov cl,[es:bx]			; get overlaid public flag byte
  1947 00000A00 52                      	push	dx				; save -> segment partition entry on stack
  1948 00000A01 268B4701                	mov ax,[es:bx+1]		; get public declaration entry segment
  1949 00000A05 07                      	pop es					; es -> segment partition entry
  1950 00000A06 26800E0F0020            	or  BYTE PTR [es:15],20h	; set end vectors written bit
  1951                                  
  1952 00000A0C F6C180                  	test	cl,80h			; see if far reference, don't physically write far vectors
  1953 00000A0F 7403                    	je  wev_writem			; near reference, write the vector
  1954 00000A11 E99F00                  	jmp NEAR PTR wev_ret	; far vector, ignore it
  1955                                  
  1956                                  wev_writem:
  1957 00000A14 50                      	push	ax				; save public declaration entry segment to stack
  1958 00000A15 26F6060F0080            	test	BYTE PTR [es:15],80h	; see if segment overlaid
  1959 00000A1B 752A                    	jne wev_segovl			; yes
  1960                                  
  1961                                  ; segment not overlaid, get master segdef length
  1962 00000A1D 268E060400              	mov es,[es:4]			; es -> segdef entry
  1963 00000A22 26A10200                	mov ax,[es:2]
  1964 00000A26 A3[0000]                	mov WORD PTR [data_offset],ax	; get offset of segment in data_offset for write_bytes
  1965 00000A29 26A10400                	mov ax,[es:4]
  1966 00000A2D A3[0200]                	mov WORD PTR [data_offset+2],ax	; get high word
  1967 00000A30 268B1E0600              	mov bx,[es:6]			; bx holds length of segment
  1968                                  
  1969 00000A35 262B1E1E00              	sub bx,[es:30]			; subtract off all end vector bytes
  1970 00000A3A 031E[1600]              	add bx,[prev_vect_bytes]	; add in previous vector bytes total for this segment
  1971 00000A3E B80700                  	mov ax,7
  1972 00000A41 F7E7                    	mul di					; compute proper adjustment for vector in ax
  1973 00000A43 01C3                    	add bx,ax				; bx holds offset to proper vector within segment
  1974 00000A45 EB1F                    	jmp SHORT wev_2			; bypass overlaid segment code
  1975                                  
  1976                                  wev_segovl:
  1977 00000A47 C706[1600]0000          	mov word [prev_vect_bytes],0	; zero previous vector bytes adjustment
  1978 00000A4D 268B1E0C00              	mov bx,[es:12]			; get length of segment in bx
  1979 00000A52 31C0                    	xor ax,ax
  1980 00000A54 A3[0000]                	mov WORD PTR [data_offset],ax	; zero the data_offset for writes to .OVL file
  1981 00000A57 A3[0200]                	mov WORD PTR [data_offset+2],ax
  1982                                  
  1983                                  ; calculate proper segment offset to write vector bytes
  1984                                  ; segment length-(total_ref-di)*7
  1985 00000A5A A1[0E00]                	mov ax,[total_ref]		; get total count
  1986 00000A5D 29F8                    	sub ax,di				; subtract off current count
  1987 00000A5F BA0700                  	mov dx,7
  1988 00000A62 F7E2                    	mul dx					; get amount to subtract off of segment length
  1989 00000A64 29C3                    	sub bx,ax				; bx holds segment offset
  1990                                  
  1991                                  wev_2:
  1992 00000A66 011E[0000]              	add WORD PTR [data_offset],bx
  1993 00000A6A 8316[0200]00            	adc WORD [data_offset+2],0
  1994                                  
  1995                                  ; calculate offset to shared vector
  1996 00000A6F B80900                  	mov ax,9
  1997 00000A72 0306[1800]              	add ax,[nearv_offset]
  1998 00000A76 29D8                    	sub ax,bx				; ax should hold offset to shared vector from near call
  1999 00000A78 A3[4F00]                	mov WORD PTR [offset_to_shared],ax 
  2000                                  
  2001 00000A7B 07                      	pop es					; es -> public declaration entry
  2002 00000A7C 26A10200                	mov ax,[es:2]			; get overlaid public number
  2003 00000A80 A3[4C00]                	mov WORD PTR [dest_id_word],ax	; save in destination id word
  2004                                  
  2005                                  ; set or reset bit 6 to reflect whether calling root or overlay
  2006 00000A83 26F6060F0001            	test	BYTE PTR [es:15],1	; see if in overlay
  2007 00000A89 7407                    	je  wev_3				; no
  2008 00000A8B 8026[4D00]BF            	and BYTE [dest_id_word+1],0bfh	; reset bit 6 to indicate calling overlay
  2009 00000A90 EB05                    	jmp SHORT wev_4			; bypass root code bit setup
  2010                                  
  2011                                  wev_3:
  2012 00000A92 800E[4D00]40            	or BYTE [dest_id_word+1],40h	; set bit 6 to indicate calling root
  2013                                  
  2014                                  wev_4:
  2015 00000A97 8CD8                    	mov ax,ds
  2016 00000A99 8EC0                    	mov es,ax				; es -> warplink data
  2017                                  
  2018 00000A9B 88CA                    	mov dl,cl				; dl holds flag byte
  2019                                  
  2020                                  wev_near:
  2021 00000A9D 80E240                  	and dl,40h				; see if near bit set
  2022 00000AA0 7411                    	je  wev_ret				; no
  2023 00000AA2 8026[4D00]7F            	and BYTE [dest_id_word+1],7fh	; reset high bit to indicate near call
  2024 00000AA7 BE[4A00]                	mov si,OFFSET public_vector_bytes wrt DGROUP	; es:si -> bytes to write
  2025 00000AAA B90700                  	mov cx,7				; write 7 bytes
  2026 00000AAD 57                      	push	di				; save critical register
  2027 00000AAE E8(0000)                	call	write_bytes
  2028 00000AB1 5F                      	pop di					; restore critical register
  2029 00000AB2 47                      	inc di					; bump count of vectored publics
  2030                                  
  2031                                  wev_ret:
  2032 00000AB3 07                      	pop es					; restore critical registers
  2033 00000AB4 5A                      	pop dx					; restore critical registers
  2034 00000AB5 59                      	pop cx
  2035 00000AB6 5B                      	pop bx
  2036 00000AB7 C3                      	ret
  2037                                  write_end_vectors   ENDP
  2038                                  
  2039                                  ;*****************************
  2040                                  ;* WRITE_OVL_RELOC           *
  2041                                  ;*****************************
  2042                                  
  2043                                  ; write relocation item to overlay file
  2044                                  ; upon entry dx == record offset
  2045                                  ; destroys ax,dx,di
  2046                                  
  2047                                  write_ovl_reloc PROC
  2048 00000AB8 A1[0000]                	mov ax,WORD PTR [data_offset]	; get program offset of data low word, high word should be zero
  2049 00000ABB 01D0                    	add ax,dx				; add in offset in data record
  2050 00000ABD 50                      	push	ax				; save it on the stack
  2051 00000ABE A1[0000]                	mov ax,[ovl_code_id]		; get current id code
  2052 00000AC1 3B06[0600]              	cmp ax,[reloc_ovl_id]		; see if matches relocation array id
  2053 00000AC5 740E                    	je  wor_2				; yes
  2054 00000AC7 E83000                  	call	flush_reloc_array	; no, flush relocation array
  2055 00000ACA 31C0                    	xor ax,ax
  2056 00000ACC A3[0800]                	mov [reloc_ovl_pos],ax	; reset relocation array position
  2057 00000ACF A1[0000]                	mov ax,[ovl_code_id]
  2058 00000AD2 A3[0600]                	mov [reloc_ovl_id],ax		; init relocation array overlay id to current value
  2059                                  
  2060                                  wor_2:
  2061 00000AD5 A1[0800]                	mov ax,[reloc_ovl_pos]
  2062                                  
  2063 00000AD8 09C0                    	or  ax,ax				; see if at zero position
  2064 00000ADA 7408                    	je  wor_3				; yes
  2065                                  
  2066 00000ADC 25FF03                  	and ax,3ffh				; see if array overflow
  2067 00000ADF 7503                    	jne wor_3				; no
  2068                                  
  2069                                  ; relocation array will overflow, flush it
  2070 00000AE1 E81600                  	call	flush_reloc_array
  2071                                  
  2072                                  wor_3:
  2073 00000AE4 8B3E[0800]              	mov di,[reloc_ovl_pos]
  2074 00000AE8 81E7FF03                	and di,3ffh				; get position in array, adjusting for any wraparound
  2075 00000AEC D1E7                    	shl di,1				; make a word offset
  2076 00000AEE 81C7[0000]              	add di,OFFSET ovl_reloc_array wrt DGROUP	; add in array's position in memory
  2077 00000AF2 58                      	pop ax					; get offset in data record off of stack
  2078 00000AF3 8905                    	mov [di],ax				; save it to the array
  2079 00000AF5 FF06[0800]              	inc word [reloc_ovl_pos]		; bump current position in array
  2080 00000AF9 C3                      	ret
  2081                                  write_ovl_reloc ENDP
  2082                                  
  2083                                  ;*****************************
  2084                                  ;* FLUSH_RELOC_ARRAY         *
  2085                                  ;*****************************
  2086                                  
  2087                                  ; flush overlay relocation array to disk
  2088                                  ; destroys ax,di
  2089                                  
  2090                                  flush_reloc_array   PROC
  2091 00000AFA 53                      	push	bx				; save critical register
  2092 00000AFB 51                      	push	cx
  2093 00000AFC 52                      	push	dx
  2094                                  
  2095 00000AFD A1[0600]                	mov ax,[reloc_ovl_id]		; get relocation array overlay
  2096 00000B00 09C0                    	or  ax,ax				; check if valid
  2097 00000B02 7477                    	je  fra_ret				; zero, no flush needed
  2098                                  
  2099 00000B04 E87800                  	call	seek_to_ovl
  2100 00000B07 8B0E[0800]              	mov cx,[reloc_ovl_pos]	; get current relocation array position
  2101 00000B0B E36E                    	jcxz    fra_ret			; no bytes to write
  2102 00000B0D D1E1                    	shl cx,1				; convert to word count
  2103 00000B0F 89CF                    	mov di,cx				; save relocation array byte count in di
  2104 00000B11 81E7FF07                	and di,7ffh				; ignore any wrap (bytes previously written)
  2105                                  
  2106 00000B15 7503                    	jne fra_1				; remainder bytes to write
  2107 00000B17 BF0008                  	mov di,800h				; even block to write
  2108                                  
  2109                                  fra_1:
  2110                                  
  2111 00000B1A 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion switch set
  2112 00000B1F 7405                    	je  fra_notclar			; no
  2113 00000B21 BA0E00                  	mov dx,14				; adjust file seek for overlay system info
  2114 00000B24 EB03                    	jmp SHORT fra_zerohigh
  2115                                  
  2116                                  fra_notclar:
  2117 00000B26 BA0A00                  	mov dx,10				; adjust file seek for overlay system info
  2118                                  
  2119                                  fra_zerohigh:
  2120 00000B29 31C9                    	xor cx,cx				; zero high word of offset
  2121                                  
  2122                                  ; if reloc_ovl_pos is > EXTDEF_MAX, must adjust past previously written chunks
  2123 00000B2B A1[0800]                	mov ax,[reloc_ovl_pos]
  2124 00000B2E D1E0                    	shl ax,1				; convert to byte count
  2125 00000B30 3D0008                  	cmp ax,800h
  2126 00000B33 7609                    	jbe fra_1a				; no previous bytes
  2127                                  
  2128 00000B35 48                      	dec ax
  2129 00000B36 2500F8                  	and ax,0f800h			; get previous byte count amount
  2130                                  
  2131 00000B39 01C2                    	add dx,ax				; adjust file offset to proper position in overlay relocation table
  2132 00000B3B 83D100                  	adc cx,0				; carry to high word
  2133                                  
  2134                                  fra_1a:
  2135 00000B3E 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay stashed in EMS/XMS
  2136 00000B43 740D                    	je  fra_noems			; no
  2137                                  
  2138 00000B45 E82B04                  	call	ems_ovl_seek	; seek to proper EMS position
  2139 00000B48 89F9                    	mov cx,di				; get count of bytes to write
  2140 00000B4A BA[0000]                	mov dx,OFFSET ovl_reloc_array wrt DGROUP	; ds:dx -> write buffer
  2141 00000B4D E80605                  	call	ems_ovl_write	; write to overlay in EMS
  2142 00000B50 EB29                    	jmp SHORT fra_ret		; bypass file i/o
  2143                                  
  2144                                  fra_noems:
  2145 00000B52 8B1E[0000]              	mov bx,[ovl_handle]
  2146 00000B56 B80142                  	mov ax,4201h			; move file pointer, offset from current file position
  2147 00000B59 CD21                    	int 21h
  2148 00000B5B E8(0000)                	call	restore_ems_map
  2149 00000B5E 7306                    	jnc fra_2				; no errors
  2150                                  
  2151                                  fra_to_doserr:
  2152 00000B60 BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
  2153 00000B63 E9(0000)                	jmp NEAR PTR dos_error	; error opening file
  2154                                  
  2155                                  fra_2:
  2156 00000B66 89F9                    	mov cx,di				; get count of bytes to write
  2157 00000B68 BA[0000]                	mov dx,OFFSET ovl_reloc_array wrt DGROUP	; ds:dx -> write buffer
  2158 00000B6B B440                    	mov ah,40h				; write to file
  2159 00000B6D CD21                    	int 21h
  2160 00000B6F E8(0000)                	call	restore_ems_map
  2161 00000B72 72EC                    	jc  fra_to_doserr		; error occurred
  2162 00000B74 39C8                    	cmp ax, cx
  2163 00000B76 B82700                  	mov ax, 27h			; insufficient disk space error
  2164 00000B79 75E5                    	jne fra_to_doserr
  2165                                  
  2166                                  fra_ret:
  2167 00000B7B 5A                      	pop dx					; restore critical register
  2168 00000B7C 59                      	pop cx
  2169 00000B7D 5B                      	pop bx
  2170 00000B7E C3                      	ret
  2171                                  flush_reloc_array   ENDP
  2172                                  
  2173                                  ;*****************************
  2174                                  ;* SEEK_TO_OVL               *
  2175                                  ;*****************************
  2176                                  
  2177                                  ; seek to overlay file position in .OVL, based on overlay identifier in ax
  2178                                  ; returns overlay file handle in bx
  2179                                  ; destroys ax,bx,cx,dx
  2180                                  
  2181                                  seek_to_ovl PROC
  2182                                  
  2183                                  ; get overlay file position from table
  2184 00000B7F 48                      	dec ax					; make identifier relative zero
  2185 00000B80 D1E0                    	shl ax,1
  2186 00000B82 D1E0                    	shl ax,1				; convert to doubleword
  2187 00000B84 89C3                    	mov bx,ax
  2188 00000B86 1E                      	push	ds				; save critical register
  2189 00000B87 8E1E[0000]              	mov ds,[ovl_filepos_blk]
  2190 00000B8B 8B17                    	mov dx,[bx]				; get low word file offset
  2191 00000B8D 8B4F02                  	mov cx,[bx+2]			; get high word file offset
  2192 00000B90 1F                      	pop ds					; restore ds -> warplink data
  2193                                  
  2194 00000B91 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay stashed in EMS/XMS
  2195 00000B96 7409                    	je  sto_seek			; no
  2196                                  
  2197 00000B98 8916[1400]              	mov WORD PTR [curr_ems_pos],dx	; save current EMS write position
  2198 00000B9C 890E[1600]              	mov WORD PTR [curr_ems_pos+2],cx
  2199 00000BA0 C3                      	ret
  2200                                  
  2201                                  ; seek to file position
  2202                                  sto_seek:
  2203 00000BA1 8B1E[0000]              	mov bx,[ovl_handle]
  2204 00000BA5 B80042                  	mov ax,4200h			; move file pointer, offset from start of file
  2205 00000BA8 CD21                    	int 21h
  2206 00000BAA E8(0000)                	call	restore_ems_map
  2207 00000BAD 7201                    	jc  sto_to_doserr		; error occurred
  2208                                  
  2209                                  sto_ret:
  2210 00000BAF C3                      	ret
  2211                                  
  2212                                  sto_to_doserr:
  2213 00000BB0 BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
  2214 00000BB3 E9(0000)                	jmp NEAR PTR dos_error	; error opening file
  2215                                  
  2216                                  seek_to_ovl ENDP
  2217                                  
  2218                                  ;*****************************
  2219                                  ;* OVL_FILE_WRITE            *
  2220                                  ;*****************************
  2221                                  
  2222                                  ; write bytes to overlay file, write to memory page if possible
  2223                                  ; upon entry [es:si] -> buffer to write from, cx == number of bytes to write,
  2224                                  ; bp==buffer end, data_offset == offset from start of program
  2225                                  ; updates si
  2226                                  ; destroys ax,bx,cx,dx,di
  2227                                  
  2228                                  ovl_file_write  PROC
  2229 00000BB6 89CF                    	mov di,cx				; save number of bytes to write in di
  2230 00000BB8 A1[0000]                	mov ax,[ovl_code_id]		; get current overlay code id
  2231 00000BBB 3B06[0A00]              	cmp ax,[ovl_page_owner]	; see if matches owner of overlay page
  2232 00000BBF 7431                    	je  ofw_2				; yes
  2233                                  
  2234                                  ; current overlay page does not match current overlay to write, zero out dirty bit table
  2235 00000BC1 31C0                    	xor ax,ax
  2236 00000BC3 A3[1C00]                	mov WORD PTR [dirty_bit_table],ax
  2237 00000BC6 A3[1E00]                	mov WORD PTR [dirty_bit_table+2],ax
  2238 00000BC9 A3[2000]                	mov WORD PTR [dirty_bit_table+4],ax
  2239 00000BCC A3[2200]                	mov WORD PTR [dirty_bit_table+6],ax
  2240 00000BCF A3[2400]                	mov WORD PTR [dirty_bit_table+8],ax
  2241 00000BD2 A3[2600]                	mov WORD PTR [dirty_bit_table+10],ax
  2242 00000BD5 A3[2800]                	mov WORD PTR [dirty_bit_table+12],ax
  2243 00000BD8 A3[2A00]                	mov WORD PTR [dirty_bit_table+14],ax
  2244                                  
  2245                                  ; need to flush page, new bytes don't map onto it
  2246                                  ofw_flush:
  2247 00000BDB E8A200                  	call	flush_ovl_page	; flush the old page to disk
  2248 00000BDE A1[0000]                	mov ax,[ovl_code_id]
  2249 00000BE1 A3[0A00]                	mov [ovl_page_owner],ax	; update owner of overlay page
  2250 00000BE4 A1[0000]                	mov ax,WORD PTR [data_offset]
  2251 00000BE7 2500F0                  	and ax,0f000h			; clear out page remainder
  2252 00000BEA A3[0C00]                	mov [ovl_page_base],ax	; save new page base
  2253 00000BED E82F01                  	call	read_new_ovl_page	; read the new overlay page from disk
  2254 00000BF0 EB1A                    	jmp SHORT ofw_write		; bypass other checking code
  2255                                  
  2256                                  ofw_2:
  2257 00000BF2 A1[0C00]                	mov ax,[ovl_page_base]	; ax holds start byte of overlay page
  2258 00000BF5 89C3                    	mov bx,ax
  2259 00000BF7 81C3FF0F                	add bx,0fffh			; bx holds highest byte of overlay page
  2260 00000BFB 8B0E[0000]              	mov cx,WORD PTR [data_offset]	; cx holds start byte of offset to write
  2261 00000BFF 89FA                    	mov dx,di				; get count of bytes to write
  2262 00000C01 4A                      	dec dx					; make relative zero
  2263 00000C02 01CA                    	add dx,cx				; dx holds highest byte to write
  2264                                  
  2265                                  ; see if highest byte to write is below page start or lowest byte to write
  2266                                  ; is above page end, forces a page flush
  2267 00000C04 39C2                    	cmp dx,ax
  2268 00000C06 72D3                    	jb  ofw_flush			; doesn't map on page
  2269                                  
  2270 00000C08 39D9                    	cmp cx,bx
  2271 00000C0A 77CF                    	ja  ofw_flush			; doesn't map onto page at all
  2272                                  
  2273                                  ; at least part of the bytes to write map onto current page
  2274                                  ofw_write:
  2275 00000C0C 8B1E[0000]              	mov bx,WORD PTR [data_offset]
  2276 00000C10 81E3FF0F                	and bx,0fffh			; convert to 4K offset
  2277 00000C14 89F9                    	mov cx,di				; get count of bytes to write
  2278 00000C16 49                      	dec cx					; make relative zero
  2279 00000C17 01D9                    	add cx,bx				; cx holds highest byte to write on page
  2280 00000C19 81F9FF0F                	cmp cx,0fffh			; see if cx is off the page
  2281 00000C1D 7603                    	jbe ofw_4				; no
  2282 00000C1F B9FF0F                  	mov cx,0fffh			; put cx at end of page
  2283                                  
  2284                                  ofw_4:
  2285 00000C22 3B0E[0E00]              	cmp cx,[ovl_high_page_byte]	; see if highest byte exceeds previous
  2286 00000C26 7604                    	jbe ofw_4a				; no
  2287 00000C28 890E[0E00]              	mov [ovl_high_page_byte],cx	; save highest byte written to value
  2288                                  
  2289                                  ofw_4a:
  2290 00000C2C 29D9                    	sub cx,bx
  2291 00000C2E 41                      	inc cx					; cx holds count of bytes to write on this page
  2292 00000C2F 29CF                    	sub di,cx				; subtract from total count of bytes to write
  2293                                  
  2294 00000C31 87DF                    	xchg bx,di				; save di value in bx
  2295 00000C33 1E                      	push	ds
  2296 00000C34 8CC2                    	mov dx,es
  2297 00000C36 A1[0000]                	mov ax,[ovl_ioblk]
  2298 00000C39 8EC0                    	mov es,ax				; es:di -> destination buffer
  2299 00000C3B 8EDA                    	mov ds,dx				; ds:si -> source buffer
  2300                                  
  2301 00000C3D 89F0                    	mov ax,si				; get offset of source
  2302 00000C3F 01C8                    	add ax,cx				; add in number of bytes to write
  2303 00000C41 7204                    	jc  ofw_buff_wrap		; overflow, buffer will wrap
  2304 00000C43 39E8                    	cmp ax,bp				; see if past buffer end for total bytes written
  2305 00000C45 7616                    	jbe ofw_no_buff_wrap	; no
  2306                                  
  2307                                  ofw_buff_wrap:
  2308 00000C47 89CA                    	mov dx,cx				; save old byte count to write
  2309 00000C49 89E9                    	mov cx,bp				; get buffer end
  2310 00000C4B 29F1                    	sub cx,si				; compute bytes to buffer end
  2311 00000C4D 89C8                    	mov ax,cx				; save byte count written this pass
  2312 00000C4F D1E9                    	shr cx,1				; convert byte count to write to words
  2313 00000C51 F3A5                    	rep movsw				; move the string
  2314 00000C53 D1D1                    	rcl cx,1				; pick up carry
  2315 00000C55 F3A4                    	rep movsb				; transfer leftover byte, if any
  2316 00000C57 31F6                    	xor si,si				; wrap source offset to start of i/o buffer
  2317 00000C59 29C2                    	sub dx,ax				; update total count, subtracting off byte count written
  2318 00000C5B 89D1                    	mov cx,dx				; get new total in cx
  2319                                  
  2320                                  ofw_no_buff_wrap:
  2321 00000C5D D1E9                    	shr cx,1				; convert byte count to write to words
  2322 00000C5F F3A5                    	rep movsw				; move the string
  2323 00000C61 D1D1                    	rcl cx,1				; pick up carry
  2324 00000C63 F3A4                    	rep movsb				; transfer leftover byte, if any
  2325                                  
  2326                                  ofw_5:
  2327 00000C65 8CD8                    	mov ax,ds
  2328 00000C67 8EC0                    	mov es,ax				; restore es -> buffer
  2329 00000C69 1F                      	pop ds					; restore ds -> warplink data
  2330 00000C6A 89DF                    	mov di,bx				; restore di value
  2331 00000C6C 09FF                    	or  di,di				; see if more bytes to write
  2332 00000C6E 740F                    	je  ofw_ret				; no
  2333                                  
  2334 00000C70 A1[0000]                	mov ax,WORD PTR [data_offset]	; get data_offset
  2335 00000C73 2500F0                  	and ax,0f000h			; clear out remainder
  2336 00000C76 050010                  	add ax,1000h			; bump to next page
  2337 00000C79 A3[0000]                	mov WORD PTR [data_offset],ax	; save back to data_offset variables
  2338 00000C7C E95CFF                  	jmp NEAR PTR ofw_flush	; loop back to flush and write bytes
  2339                                  
  2340                                  ofw_ret:
  2341 00000C7F C3                      	ret
  2342                                  ovl_file_write  ENDP
  2343                                  
  2344                                  ;*****************************
  2345                                  ;* FLUSH_OVL_PAGE            *
  2346                                  ;*****************************
  2347                                  
  2348                                  ; flush overlay page to disk
  2349                                  ; destroys ax,bx,cx,dx
  2350                                  
  2351                                  flush_ovl_page  PROC
  2352 00000C80 A1[0A00]                	mov ax,[ovl_page_owner]	; get id of overlay owning page
  2353 00000C83 09C0                    	or  ax,ax				; make sure non-null
  2354 00000C85 7501                    	jne fop_flush			; yes
  2355 00000C87 C3                      	ret						; null, no page to flush
  2356                                  
  2357                                  fop_flush:
  2358 00000C88 E8F4FE                  	call	seek_to_ovl		; seek to overlay file of overlay owning page (id in ax)
  2359                                  
  2360                                  ; read system info bytes
  2361 00000C8B 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion switch set
  2362 00000C90 7405                    	je  fop_notclar			; no
  2363 00000C92 B90E00                  	mov cx,14				; 14 system bytes, 7 words
  2364 00000C95 EB03                    	jmp SHORT fop_1
  2365                                  
  2366                                  fop_notclar:
  2367 00000C97 B90A00                  	mov cx,10				; 10 system bytes, 5 words
  2368                                  
  2369                                  fop_1:
  2370 00000C9A BA[0000]                	mov dx,OFFSET ovl_sys_info wrt DGROUP	; ds:dx -> read buffer
  2371 00000C9D 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay in EMS/XMS
  2372 00000CA2 7405                    	je  fop_noems			; no
  2373 00000CA4 E8D502                  	call	ems_ovl_read	; read from EMS
  2374 00000CA7 EB0F                    	jmp SHORT fop_2
  2375                                  
  2376                                  fop_noems:
  2377 00000CA9 B43F                    	mov ah,3fh				; read file
  2378 00000CAB CD21                    	int 21h
  2379 00000CAD E8(0000)                	call	restore_ems_map
  2380 00000CB0 7306                    	jnc fop_2
  2381                                  
  2382                                  fop_to_doserr:
  2383 00000CB2 BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
  2384 00000CB5 E9(0000)                	jmp NEAR PTR dos_error	; error opening file
  2385                                  
  2386                                  ; seek past relocation table to proper overlay code page
  2387                                  fop_2:
  2388 00000CB8 8B16[0200]              	mov dx,[ovl_sys_info+2]	; get offset to overlay code
  2389 00000CBC 31C9                    	xor cx,cx				; zero high word of offset
  2390 00000CBE 0316[0C00]              	add dx,[ovl_page_base]	; add in overlay code base
  2391 00000CC2 83D100                  	adc cx,0				; carry to high word
  2392                                  
  2393 00000CC5 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion switch set
  2394 00000CCA 7405                    	je  fop_notclar2		; no
  2395 00000CCC 83EA0E                  	sub dx,14				; subtract off system info bytes already read
  2396 00000CCF EB03                    	jmp SHORT fop_3
  2397                                  
  2398                                  fop_notclar2:
  2399 00000CD1 83EA0A                  	sub dx,10				; subtract off system info bytes already read
  2400                                  
  2401                                  fop_3:
  2402 00000CD4 83D900                  	sbb cx,0				; borrow from high word
  2403 00000CD7 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay in EMS/XMS
  2404 00000CDC 7405                    	je  fop_4				; no
  2405                                  
  2406 00000CDE E89202                  	call	ems_ovl_seek	; read from EMS
  2407 00000CE1 EB0A                    	jmp SHORT fop_5
  2408                                  
  2409                                  fop_4:
  2410 00000CE3 B80142                  	mov ax,4201h			; move file pointer, offset from current file position
  2411 00000CE6 CD21                    	int 21h
  2412 00000CE8 E8(0000)                	call	restore_ems_map
  2413 00000CEB 72C5                    	jc  fop_to_doserr		; error occurred
  2414                                  
  2415                                  fop_5:
  2416 00000CED A1[0000]                	mov ax,[ovl_ioblk]
  2417 00000CF0 8B0E[0E00]              	mov cx,[ovl_high_page_byte]	; get count of bytes to write, relative zero
  2418 00000CF4 41                      	inc cx					; make relative 1
  2419 00000CF5 31D2                    	xor dx,dx				; zero offset
  2420 00000CF7 1E                      	push	ds				; save ds -> warplink data
  2421                                  
  2422 00000CF8 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay in EMS/XMS
  2423 00000CFD 8ED8                    	mov ds,ax				; ds:dx -> write buffer, NO CHANGE TO FLAGS
  2424 00000CFF 7406                    	je  fop_6				; no
  2425 00000D01 E85203                  	call	ems_ovl_write
  2426 00000D04 1F                      	pop ds					; restore ds -> warplink data
  2427 00000D05 EB11                    	jmp SHORT fop_7
  2428                                  
  2429                                  fop_6:
  2430 00000D07 B440                    	mov ah,40h				; write to file
  2431 00000D09 CD21                    	int 21h
  2432 00000D0B E8(0000)                	call	restore_ems_map
  2433                                  
  2434 00000D0E 1F                      	pop ds					; restore ds -> warplink data
  2435 00000D0F 72A1                    	jc  fop_to_doserr		; error occurred
  2436 00000D11 39C8                    	cmp ax, cx
  2437 00000D13 B82700                  	mov ax, 27h			; insufficient disk space error
  2438 00000D16 759A                    	jne fop_to_doserr
  2439                                  
  2440                                  fop_7:
  2441 00000D18 C706[0E00]0000          	mov word [ovl_high_page_byte],0	; re-init highest page byte written
  2442                                  
  2443                                  fop_ret:
  2444 00000D1E C3                      	ret
  2445                                  flush_ovl_page  ENDP
  2446                                  
  2447                                  ;*****************************
  2448                                  ;* READ_NEW_OVL_PAGE         *
  2449                                  ;*****************************
  2450                                  
  2451                                  ; read new overlay page in from disk, if necessary (checked from dirty bit table)
  2452                                  ; otherwise just zero out page.
  2453                                  ; This assumes that binary data from one overlaid code segment is not intermixed
  2454                                  ; with binary data from another overlaid code segment
  2455                                  ; ovl_page_base holds offset in overlay file
  2456                                  ; destroys ax,bx,cx,dx
  2457                                  
  2458                                  read_new_ovl_page   PROC
  2459 00000D1F 56                      	push	si				; save critical register
  2460                                  
  2461 00000D20 A0[0D00]                	mov al,BYTE PTR [ovl_page_base+1]	; get high byte of offset (always on 4K boundary)
  2462 00000D23 30E4                    	xor ah,ah				; ax holds offset/256
  2463 00000D25 D0E8                    	shr al,1				; /512
  2464 00000D27 D0E8                    	shr al,1				; /1024
  2465 00000D29 D0E8                    	shr al,1				; /2048
  2466 00000D2B D0E8                    	shr al,1				; /4096
  2467 00000D2D BB[1C00]                	mov bx,OFFSET dirty_bit_table wrt DGROUP
  2468 00000D30 01C3                    	add bx,ax				; bx offsets to proper dirty bit (byte)
  2469 00000D32 8A07                    	mov al,[bx]				; get dirty bit status
  2470 00000D34 08C0                    	or  al,al				; see if dirty bit set
  2471 00000D36 754A                    	jne rn_dirtyset			; yes
  2472                                  
  2473 00000D38 FEC4                    	inc ah					; ah==1
  2474 00000D3A 8827                    	mov [bx],ah				; set dirty bit for future reads
  2475                                  
  2476                                  ; 12/29/92
  2477                                  ; if overlay size <4K (next overlay pos-current overlay pos), use that
  2478                                  ; figure for zero'ing
  2479 00000D3C A1[0000]                	mov ax,[ovl_code_id]
  2480 00000D3F 3B06[0000]              	cmp	ax,[ovl_count]
  2481 00000D43 7329                    	jae	rn_2048				; last overlay, no next to compute size from
  2482                                  
  2483 00000D45 48                      	dec ax					; make identifier relative zero
  2484 00000D46 D1E0                    	shl ax,1
  2485 00000D48 D1E0                    	shl ax,1				; convert to doubleword
  2486 00000D4A 89C3                    	mov bx,ax
  2487 00000D4C 1E                      	push	ds				; save critical register
  2488 00000D4D 8E1E[0000]              	mov ds,[ovl_filepos_blk]
  2489 00000D51 8B5704                  	mov	dx,[bx+4]			; get next overlay low word file offset
  2490 00000D54 8B4F06                  	mov	cx,[bx+6]			; get next overlay high word file offset
  2491 00000D57 2B17                    	sub	dx,[bx]				; subtract off current overlay position
  2492 00000D59 1B4F02                  	sbb	cx,[bx+2]
  2493 00000D5C 1F                      	pop ds					; restore ds -> warplink data
  2494 00000D5D 09C9                    	or	cx,cx				; see if >64K
  2495 00000D5F 750D                    	jne	rn_2048				; yes, use default 2K words
  2496 00000D61 81FA0010                	cmp	dx,4096				; see if >=4K
  2497 00000D65 7307                    	jae	rn_2048				; yes, use default 2K words
  2498 00000D67 89D1                    	mov	cx,dx
  2499 00000D69 41                      	inc	cx
  2500 00000D6A D1E9                    	shr	cx,1				; convert to words
  2501 00000D6C EB03                    	jmp	SHORT rn_zero
  2502                                  
  2503                                  rn_2048:
  2504 00000D6E B90008                  	mov cx,2048				; zero out 4K page (2K words)
  2505                                  
  2506                                  rn_zero:
  2507 00000D71 06                      	push	es				; save critical registers
  2508 00000D72 57                      	push	di
  2509 00000D73 A1[0000]                	mov ax,[ovl_ioblk]
  2510 00000D76 8EC0                    	mov es,ax
  2511 00000D78 31C0                    	xor ax,ax
  2512 00000D7A 89C7                    	mov di,ax				; es:di -> start of page
  2513 00000D7C F3AB                    	rep stosw
  2514 00000D7E 5F                      	pop di					; restore critical registers
  2515 00000D7F 07                      	pop es
  2516 00000D80 5E                      	pop	si
  2517 00000D81 C3                      	ret						; done zero'ing page, return
  2518                                  
  2519                                  rn_dirtyset:
  2520 00000D82 A1[0000]                	mov ax,[ovl_code_id]
  2521 00000D85 E8F7FD                  	call	seek_to_ovl		; seek to overlay file
  2522                                  
  2523                                  ; read system info bytes
  2524 00000D88 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion switch set
  2525 00000D8D 7405                    	je  rn_notclar			; no
  2526 00000D8F B90E00                  	mov cx,14				; 14 system bytes, 7 words
  2527 00000D92 EB03                    	jmp SHORT rn_1
  2528                                  
  2529                                  rn_notclar:
  2530 00000D94 B90A00                  	mov cx,10				; 10 system bytes, 5 words
  2531                                  
  2532                                  rn_1:
  2533 00000D97 BA[0000]                	mov dx,OFFSET ovl_sys_info wrt DGROUP	; ds:dx -> read buffer
  2534 00000D9A 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay in EMS/XMS
  2535 00000D9F 7405                    	je  rn_noems			; no
  2536 00000DA1 E8D801                  	call	ems_ovl_read	; read from EMS
  2537 00000DA4 EB0F                    	jmp SHORT rn_2
  2538                                  
  2539                                  rn_noems:
  2540 00000DA6 B43F                    	mov ah,3fh				; read file
  2541 00000DA8 CD21                    	int 21h
  2542 00000DAA E8(0000)                	call	restore_ems_map
  2543 00000DAD 7306                    	jnc rn_2
  2544                                  
  2545                                  rn_to_doserr:
  2546 00000DAF BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
  2547 00000DB2 E9(0000)                	jmp NEAR PTR dos_error	; error opening file
  2548                                  
  2549                                  ; seek past relocation table to proper overlay code page
  2550                                  rn_2:
  2551 00000DB5 8B16[0200]              	mov dx,[ovl_sys_info+2]	; get offset to overlay code
  2552 00000DB9 31C9                    	xor cx,cx				; zero high word of offset
  2553 00000DBB 0316[0C00]              	add dx,[ovl_page_base]	; add in overlay code base
  2554 00000DBF 83D100                  	adc cx,0				; carry to high word
  2555                                  
  2556 00000DC2 803E[0000]00            	cmp byte [is_clarion],0		; see if clarion switch set
  2557 00000DC7 7405                    	je  rn_notclar2			; no
  2558 00000DC9 83EA0E                  	sub dx,14				; subtract off system info bytes already read
  2559 00000DCC EB03                    	jmp SHORT rn_3
  2560                                  
  2561                                  rn_notclar2:
  2562 00000DCE 83EA0A                  	sub dx,10				; subtract off system info bytes already read
  2563                                  
  2564                                  rn_3:
  2565 00000DD1 83D900                  	sbb cx,0				; borrow from high word
  2566                                  
  2567 00000DD4 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay in EMS/XMS
  2568 00000DD9 7405                    	je  rn_4				; no
  2569                                  
  2570 00000DDB E89501                  	call	ems_ovl_seek	; read from EMS
  2571 00000DDE EB0A                    	jmp SHORT rn_5
  2572                                  
  2573                                  rn_4:
  2574 00000DE0 B80142                  	mov ax,4201h			; move file pointer, offset from current file position
  2575 00000DE3 CD21                    	int 21h
  2576 00000DE5 E8(0000)                	call	restore_ems_map
  2577 00000DE8 72C5                    	jc  rn_to_doserr		; error occurred
  2578                                  
  2579                                  rn_5:
  2580 00000DEA A1[0000]                	mov ax,[ovl_ioblk]
  2581                                  
  2582                                  ; 12/29/92
  2583 00000DED 803E[0500]00            	cmp	BYTE [ovl_sys_info+5],0	; see if 4K or greater overlay code size (100h paras, ignore low byte)
  2584 00000DF2 750E                    	jne	rn_4096				; yes
  2585 00000DF4 8B0E[0400]              	mov	cx,WORD PTR [ovl_sys_info+4]	; only read in as many bytes as in overlay code
  2586 00000DF8 01C9                    	add	cx,cx				; convert paras to bytes, *2
  2587 00000DFA 01C9                    	add	cx,cx				; *4
  2588 00000DFC 01C9                    	add	cx,cx				; *8
  2589 00000DFE 01C9                    	add	cx,cx				; *16
  2590 00000E00 EB03                    	jmp	SHORT rn_read
  2591                                  
  2592                                  rn_4096:
  2593 00000E02 B90010                  	mov cx,4096				; read 4K bytes
  2594                                  
  2595                                  rn_read:
  2596 00000E05 31D2                    	xor dx,dx				; zero offset
  2597 00000E07 1E                      	push	ds				; save ds -> warplink data
  2598                                  
  2599 00000E08 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see if overlay in EMS/XMS
  2600 00000E0D 8ED8                    	mov ds,ax				; ds:dx -> write buffer, NO CHANGE TO FLAGS
  2601 00000E0F 7405                    	je  rn_6				; overlay not in EMS/XMS
  2602                                  
  2603                                  ; 12/29/92
  2604 00000E11 E86801                  	call	ems_ovl_read
  2605 00000E14 EB09                    	jmp SHORT rn_done
  2606                                  
  2607                                  rn_6:
  2608 00000E16 B43F                    	mov ah,3fh				; read file
  2609 00000E18 CD21                    	int 21h
  2610 00000E1A E8(0000)                	call	restore_ems_map
  2611 00000E1D 7290                    	jc  rn_to_doserr		; error occurred
  2612                                  
  2613                                  rn_done:
  2614 00000E1F 1F                      	pop	ds					; restore ds -> warplink data
  2615 00000E20 5E                      	pop	si					; restore critical register
  2616 00000E21 C3                      	ret
  2617                                  read_new_ovl_page   ENDP
  2618                                  
  2619                                  ;*****************************
  2620                                  ;* WRITE_CLAR_DATA           *
  2621                                  ;*****************************
  2622                                  
  2623                                  ; write bytes to overlaid Clarion _DT or _DAT segment
  2624                                  ; upon entry [es:si] -> buffer to write from, cx == number of bytes to write,
  2625                                  ; updates si
  2626                                  ; destroys ax,bx,cx,dx,di
  2627                                  
  2628                                  write_clar_data PROC
  2629 00000E22 51                      	push	cx				; save bytes to write
  2630 00000E23 A1[0000]                	mov ax,[ovl_data_id]		; get overlay identifier for overlaid data
  2631 00000E26 D1E8                    	shr ax,1				; convert to byte value
  2632 00000E28 E854FD                  	call	seek_to_ovl		; seek to start of code
  2633                                  
  2634                                  ; read system info bytes
  2635                                  wcd_readsys:
  2636 00000E2B B90E00                  	mov cx,14				; 14 system bytes, 7 words
  2637 00000E2E BA[0000]                	mov dx,OFFSET ovl_sys_info wrt DGROUP	; ds:dx -> read buffer
  2638                                  
  2639 00000E31 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see overlay in EMS/XMS
  2640 00000E36 7405                    	je  wcd_1				; no
  2641 00000E38 E84101                  	call	ems_ovl_read
  2642 00000E3B EB0F                    	jmp SHORT wcd_2
  2643                                  
  2644                                  wcd_1:
  2645 00000E3D B43F                    	mov ah,3fh				; read file
  2646 00000E3F CD21                    	int 21h
  2647 00000E41 E8(0000)                	call	restore_ems_map
  2648 00000E44 7306                    	jnc wcd_2
  2649 00000E46 BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
  2650 00000E49 E9(0000)                	jmp NEAR PTR dos_error	; error opening file
  2651                                  
  2652                                  ; seek past relocation table to proper overlay code page
  2653                                  wcd_2:
  2654 00000E4C 8B16[0200]              	mov dx,[ovl_sys_info+2]	; get offset to overlay code
  2655 00000E50 31C9                    	xor cx,cx				; zero high word of offset
  2656 00000E52 83EA0E                  	sub dx,14				; subtract off system info bytes already read
  2657 00000E55 83D900                  	sbb cx,0				; borrow from high word
  2658                                  
  2659 00000E58 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see overlay in EMS/XMS
  2660 00000E5D 7405                    	je  wcd_2a				; no
  2661 00000E5F E81101                  	call	ems_ovl_seek
  2662 00000E62 EB08                    	jmp SHORT wcd_2b
  2663                                  
  2664                                  wcd_2a:
  2665 00000E64 B80142                  	mov ax,4201h			; move file pointer, offset from current file position
  2666 00000E67 CD21                    	int 21h
  2667 00000E69 E8(0000)                	call	restore_ems_map
  2668                                  
  2669                                  wcd_2b:
  2670 00000E6C 8B16[0400]              	mov dx,[ovl_sys_info+4]	; get overlay code size in paragraphs, position past it
  2671 00000E70 31C9                    	xor cx,cx				; zero high word of offset
  2672 00000E72 D1E2                    	shl dx,1
  2673 00000E74 D1D1                    	rcl cx,1				; x2
  2674 00000E76 D1E2                    	shl dx,1
  2675 00000E78 D1D1                    	rcl cx,1				; x4
  2676 00000E7A D1E2                    	shl dx,1
  2677 00000E7C D1D1                    	rcl cx,1				; x8
  2678 00000E7E D1E2                    	shl dx,1
  2679 00000E80 D1D1                    	rcl cx,1				; x16, converted to bytes
  2680                                  
  2681 00000E82 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see overlay in EMS/XMS
  2682 00000E87 7405                    	je  wcd_2c				; no
  2683 00000E89 E8E700                  	call	ems_ovl_seek
  2684 00000E8C EB08                    	jmp SHORT wcd_2d
  2685                                  
  2686                                  wcd_2c:
  2687 00000E8E B80142                  	mov ax,4201h			; move file pointer, offset from current file position
  2688 00000E91 CD21                    	int 21h
  2689 00000E93 E8(0000)                	call	restore_ems_map
  2690                                  
  2691                                  wcd_2d:
  2692 00000E96 A1[0000]                	mov ax,[ovl_data_id]		; get overlay identifier for overlaid code
  2693 00000E99 C706[0000]0000          	mov word [ovl_data_id],0		; zero out the overlay identifier after use
  2694 00000E9F 2401                    	and al,1				; see if _DT segment or _DAT segment
  2695 00000EA1 742A                    	je   wcd_3				; _DT segment, at start of code
  2696                                  
  2697                                  ; need to position to _DAT segment, past _DT segment
  2698 00000EA3 8B16[0600]              	mov dx,[ovl_sys_info+6]	; get _DT segment size in paragraphs, position past it
  2699 00000EA7 31C9                    	xor cx,cx				; zero high word of offset
  2700 00000EA9 D1E2                    	shl dx,1
  2701 00000EAB D1D1                    	rcl cx,1				; x2
  2702 00000EAD D1E2                    	shl dx,1
  2703 00000EAF D1D1                    	rcl cx,1				; x4
  2704 00000EB1 D1E2                    	shl dx,1
  2705 00000EB3 D1D1                    	rcl cx,1				; x8
  2706 00000EB5 D1E2                    	shl dx,1
  2707 00000EB7 D1D1                    	rcl cx,1				; x16, converted to bytes
  2708                                  
  2709 00000EB9 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see overlay in EMS/XMS
  2710 00000EBE 7405                    	je  wcd_2e				; no
  2711 00000EC0 E8B000                  	call	ems_ovl_seek
  2712 00000EC3 EB08                    	jmp SHORT wcd_3
  2713                                  
  2714                                  wcd_2e:
  2715 00000EC5 B80142                  	mov ax,4201h			; move file pointer, offset from current file position
  2716 00000EC8 CD21                    	int 21h
  2717 00000ECA E8(0000)                	call	restore_ems_map
  2718                                  
  2719                                  wcd_3:
  2720 00000ECD 8B16[0000]              	mov dx,WORD PTR [rec_offset]	; get LEDATA enumerated data offset
  2721 00000ED1 31C9                    	xor cx,cx				; zap high word
  2722                                  
  2723 00000ED3 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see overlay in EMS/XMS
  2724 00000ED8 7405                    	je  wcd_3a				; no
  2725 00000EDA E89600                  	call	ems_ovl_seek
  2726 00000EDD EB08                    	jmp SHORT wcd_3b
  2727                                  
  2728                                  wcd_3a:
  2729 00000EDF B80142                  	mov ax,4201h			; move file pointer, offset from current file position
  2730 00000EE2 CD21                    	int 21h
  2731 00000EE4 E8(0000)                	call	restore_ems_map
  2732                                  
  2733                                  wcd_3b:
  2734 00000EE7 59                      	pop cx					; restore number of bytes to write
  2735 00000EE8 89F2                    	mov dx,si				; dx -> write buffer
  2736                                  
  2737 00000EEA 89F0                    	mov ax,si				; get offset of source
  2738 00000EEC 01C8                    	add ax,cx				; add in number of bytes to write
  2739 00000EEE 7204                    	jc  wcd_buff_wrap		; overflow, buffer will wrap
  2740 00000EF0 39E8                    	cmp ax,bp				; see if past buffer end for total bytes written
  2741 00000EF2 7611                    	jbe wcd_no_buff_wrap	; no
  2742                                  
  2743                                  wcd_buff_wrap:
  2744 00000EF4 89CF                    	mov di,cx				; save old byte count to write
  2745 00000EF6 89E9                    	mov cx,bp				; get buffer end
  2746 00000EF8 29F1                    	sub cx,si				; compute bytes to buffer end
  2747 00000EFA 29CF                    	sub di,cx				; update total count, subtracting off byte count written this pass
  2748                                  
  2749 00000EFC E80C00                  	call	trans_clar_data	; write clarion data
  2750                                  
  2751 00000EFF 89F9                    	mov cx,di				; get new total bytes to write in cx
  2752 00000F01 31F6                    	xor si,si				; wrap source offset to start of i/o buffer
  2753 00000F03 89F2                    	mov dx,si				; update start of write buffer
  2754                                  
  2755                                  wcd_no_buff_wrap:
  2756 00000F05 01CE                    	add si,cx				; update si past bytes written
  2757                                  
  2758 00000F07 E80100                  	call	trans_clar_data	; write clarion data
  2759 00000F0A C3                      	ret
  2760                                  
  2761                                  write_clar_data ENDP
  2762                                  
  2763                                  ;*****************************
  2764                                  ;* TRANS_CLAR_DATA           *
  2765                                  ;*****************************
  2766                                  
  2767                                  ; write clarion data to file,
  2768                                  ; if EMS write clarion data to transfer buffer first
  2769                                  ; upon entry es:dx -> write buffer, cx holds bytes to write,
  2770                                  ; bx holds file handle, if overlay on disk
  2771                                  ; destroys ax,bx,cx,dx
  2772                                  
  2773                                  trans_clar_data PROC
  2774 00000F0B 803E[0000]00            	cmp byte [is_emsxms_ovl],0		; see overlay in EMS/XMS
  2775 00000F10 7433                    	je  tcd_2				; no
  2776                                  
  2777                                  tcd_wloop:
  2778 00000F12 51                      	push	cx				; save bytes to write
  2779 00000F13 81F90040                	cmp cx,16384			; don't write more than 16K each pass
  2780 00000F17 7603                    	jbe tcd_write
  2781 00000F19 B90040                  	mov cx,16384
  2782                                  
  2783                                  ; move bytes to write to transfer buffer first, then make es:dx -> transfer buffer
  2784                                  tcd_write:
  2785 00000F1C 06                      	push	es				; save critical register
  2786 00000F1D 56                      	push	si
  2787 00000F1E 57                      	push	di
  2788 00000F1F 8CC0                    	mov ax,es				; save source segment
  2789 00000F21 8E06[0000]              	mov es,[ems_trans_block]
  2790 00000F25 31FF                    	xor di,di				; es:di -> destination (transfer buffer)
  2791 00000F27 8ED8                    	mov ds,ax
  2792 00000F29 89D6                    	mov si,dx				; ds:si -> source
  2793 00000F2B 89C8                    	mov ax,cx				; save bytes to write
  2794 00000F2D D1E9                    	shr cx,1				; convert byte count to read to words
  2795 00000F2F F3A5                    	rep movsw				; move the string
  2796 00000F31 D1D1                    	rcl cx,1				; pick up carry
  2797 00000F33 F3A4                    	rep movsb				; transfer leftover byte, if any
  2798 00000F35 89C1                    	mov cx,ax				; restore bytes to write
  2799 00000F37 31D2                    	xor dx,dx				; es:dx -> transfer buffer
  2800 00000F39 B8[ssss]                	mov ax,DGROUP
  2801 00000F3C 8ED8                    	mov ds,ax				; ds -> warplink data
  2802                                  
  2803 00000F3E 06                      	push	es
  2804 00000F3F 1F                      	pop	ds					; ds:dx  -> write buffer
  2805 00000F40 E81301                  	call	ems_ovl_write
  2806 00000F43 EB18                    	jmp SHORT wcd_5
  2807                                  
  2808                                  tcd_2:
  2809 00000F45 06                      	push	es
  2810 00000F46 1F                      	pop	ds					; ds:dx  -> write buffer
  2811 00000F47 B440                    	mov ah,40h				; write to file
  2812 00000F49 CD21                    	int 21h
  2813 00000F4B E8(0000)                	call	restore_ems_map
  2814 00000F4E 721D                    	jc  tcd_to_doserr		; error occurred
  2815 00000F50 39C8                    	cmp ax, cx
  2816 00000F52 B82700                  	mov ax, 27h			; insufficient disk space error
  2817 00000F55 7516                    	jne tcd_to_doserr
  2818 00000F57 B8[ssss]                	mov ax,DGROUP
  2819 00000F5A 8ED8                    	mov ds,ax				; ds -> warplink data
  2820 00000F5C C3                      	ret
  2821                                  
  2822                                  wcd_5:
  2823 00000F5D 5F                      	pop di
  2824 00000F5E 5E                      	pop si
  2825 00000F5F 07                      	pop es
  2826 00000F60 B8[ssss]                	mov ax,DGROUP
  2827 00000F63 8ED8                    	mov ds,ax				; ds -> warplink data
  2828                                  
  2829 00000F65 59                      	pop cx
  2830 00000F66 81E90040                	sub cx,16384			; subtract off max bytes written
  2831 00000F6A 77A6                    	ja  tcd_wloop			; more bytes to write
  2832                                  
  2833                                  tcd_ret:
  2834 00000F6C C3                      	ret
  2835                                  
  2836                                  tcd_to_doserr:
  2837 00000F6D BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
  2838 00000F70 E9(0000)                	jmp NEAR PTR dos_error	; error opening file
  2839                                  
  2840                                  trans_clar_data ENDP
  2841                                  
  2842                                  ;*****************************
  2843                                  ;* EMS_OVL_SEEK              *
  2844                                  ;*****************************
  2845                                  
  2846                                  ; seek to overlay page/position in EMS/XMS, relative to curr_ems_pos,
  2847                                  ; analogous to seek from current file position, function 4201h
  2848                                  ; upon entry cx:dx -> file position relative to curr_ems_pos
  2849                                  ; destroys ax,bx,cx,dx
  2850                                  
  2851                                  ems_ovl_seek    PROC
  2852 00000F73 0116[1400]              	add WORD PTR [curr_ems_pos],dx
  2853 00000F77 110E[1600]              	adc WORD PTR [curr_ems_pos+2],cx	; carry to high word
  2854 00000F7B C3                      	ret
  2855                                  ems_ovl_seek    ENDP
  2856                                  
  2857                                  ;*****************************
  2858                                  ;* EMS_OVL_READ              *
  2859                                  ;*****************************
  2860                                  
  2861                                  ; read bytes from overlay in EMS/XMS at curr_ems_pos
  2862                                  ; ds:dx -> read buffer, cx holds bytes to read
  2863                                  ; do NOT assume ds -> DGROUP upon entry
  2864                                  ; destroys ax,bx,cx,dx
  2865                                  
  2866                                  ems_ovl_read    PROC
  2867 00000F7C 8CDB                    	mov bx,ds				; save -> write buffer
  2868 00000F7E B8[ssss]                	mov ax,DGROUP
  2869 00000F81 8ED8                    	mov ds,ax				; ds -> warplink data
  2870                                  
  2871 00000F83 803E[0200]00            	cmp byte [ovl_in_xms],0		; see if overlay file in XMS
  2872 00000F88 7402                    	je  eor_ems				; no, in EMS
  2873 00000F8A EB70                    	jmp NEAR PTR xms_ovl_read
  2874                                  
  2875                                  eor_ems:
  2876 00000F8C 56                      	push	si				; save critical register
  2877 00000F8D 57                      	push	di
  2878 00000F8E 06                      	push	es
  2879 00000F8F FF36[0000]              	push	WORD [ems_currmap]	; save current logical state of physical page 0
  2880                                  
  2881 00000F93 8EC3                    	mov	es,bx				; es -> read buffer
  2882 00000F95 53                      	push	bx				; save -> read buffer
  2883                                  
  2884 00000F96 89D7                    	mov di,dx				; es:di -> read buffer
  2885 00000F98 8B16[1600]              	mov dx,WORD PTR [curr_ems_pos+2]
  2886 00000F9C A1[1400]                	mov ax,WORD PTR [curr_ems_pos]
  2887 00000F9F 89C6                    	mov si,ax
  2888 00000FA1 81E6FF3F                	and si,16383			; si offsets into EMS page
  2889 00000FA5 E87BF5                  	call	convert_to_page	; ax holds 16K page of position
  2890                                  
  2891 00000FA8 010E[1400]              	add WORD PTR [curr_ems_pos],cx	; adjust for bytes read
  2892 00000FAC 8316[1600]00            	adc WORD [curr_ems_pos+2],0	; carry to high word
  2893 00000FB1 0306[1A00]              	add ax,[ems_first_ovl]	; adjust for first page used
  2894                                  
  2895 00000FB5 89C3                    	mov bx,ax				; bx holds EMS logical page
  2896 00000FB7 30C0                    	xor al,al
  2897 00000FB9 E8(0000)                	call	map_ems_page	; map in proper page
  2898                                  
  2899 00000FBC 8E1E[0000]              	mov ds,[ems_base]			; ds:si -> source buffer in EMS
  2900                                  
  2901                                  eor_readloop:
  2902 00000FC0 89F0                    	mov ax,si				; check if read from more than one page
  2903 00000FC2 01C8                    	add ax,cx
  2904 00000FC4 720F                    	jc  eor_offpage			; carry implies read off page
  2905 00000FC6 3D0040                  	cmp ax,16384			; check page limit
  2906 00000FC9 770A                    	ja  eor_offpage			; off of page
  2907 00000FCB D1E9                    	shr cx,1				; convert byte count to read to words
  2908 00000FCD F3A5                    	rep movsw				; move the string
  2909 00000FCF D1D1                    	rcl cx,1				; pick up carry
  2910 00000FD1 F3A4                    	rep movsb				; transfer leftover byte, if any
  2911 00000FD3 EB1C                    	jmp SHORT eor_2
  2912                                  
  2913                                  eor_offpage:
  2914 00000FD5 B80040                  	mov ax,16384
  2915 00000FD8 29F0                    	sub ax,si				; ax holds bytes to read on page
  2916 00000FDA 91                      	xchg    ax,cx			; cx holds bytes to read on page, ax holds total bytes
  2917 00000FDB 29C8                    	sub ax,cx				; ax holds bytes to read beside current page
  2918 00000FDD D1E9                    	shr cx,1				; convert byte count to read to words
  2919 00000FDF F3A5                    	rep movsw				; move the string
  2920 00000FE1 D1D1                    	rcl cx,1				; pick up carry
  2921 00000FE3 F3A4                    	rep movsb				; transfer leftover byte, if any
  2922 00000FE5 89C1                    	mov cx,ax				; update total bytes to read
  2923 00000FE7 31F6                    	xor si,si				; position to start of next page
  2924 00000FE9 43                      	inc bx
  2925 00000FEA 30C0                    	xor al,al
  2926 00000FEC E8(0000)                	call	map_ems_page	; map in next page
  2927 00000FEF EBCF                    	jmp SHORT eor_readloop	; loop to read more bytes
  2928                                  
  2929                                  eor_2:
  2930 00000FF1 1F                      	pop	ds					; restore ds -> read buffer
  2931                                  
  2932                                  ; restore previous logical state of physical page 0
  2933 00000FF2 30C0                    	xor al,al
  2934 00000FF4 5B                      	pop bx
  2935 00000FF5 E8(0000)                	call	map_ems_page
  2936 00000FF8 07                      	pop es					; restore critical register
  2937 00000FF9 5F                      	pop di
  2938 00000FFA 5E                      	pop si
  2939 00000FFB C3                      	ret
  2940                                  ems_ovl_read    ENDP
  2941                                  
  2942                                  ;*****************************
  2943                                  ;* XMS_OVL_READ              *
  2944                                  ;*****************************
  2945                                  
  2946                                  ; read bytes from overlay in XMS at curr_ems_pos
  2947                                  ; bx:dx -> read buffer, cx holds bytes to read
  2948                                  ; safe to assume ds -> DGROUP upon entry
  2949                                  ; destroys ax,bx,cx,dx
  2950                                  
  2951                                  xms_ovl_read    PROC
  2952 00000FFC 53                      	push	bx				; save -> read buffer
  2953 00000FFD 56                      	push	si				; save critical register
  2954 00000FFE 891E[6A00]              	mov WORD PTR [ovl_empb.es_dest_offset+2],bx
  2955                                  
  2956 00001002 A1[1C00]                	mov ax,[xms_ovl_handle]
  2957 00001005 A3[6000]                	mov [ovl_empb.es_src_handle],ax	; source is XMS memory
  2958 00001008 31C0                    	xor ax,ax
  2959 0000100A A3[5E00]                	mov WORD PTR [ovl_empb.es_len+2],ax	; zero high word of block length
  2960 0000100D A3[6600]                	mov [ovl_empb.es_dest_handle],ax	; destination is conventional memory
  2961                                  
  2962                                  xor_loop:
  2963 00001010 89C8                    	mov ax,cx
  2964 00001012 24FE                    	and al,0feh				; round down to word boundary for XMM acceptable length
  2965 00001014 A3[5C00]                	mov WORD PTR [ovl_empb.es_len],ax	; length of block to transfer low word
  2966 00001017 A1[1400]                	mov ax,WORD PTR [curr_ems_pos]	; compute source offset
  2967 0000101A A3[6200]                	mov WORD PTR [ovl_empb.es_src_offset],ax
  2968 0000101D A1[1600]                	mov ax,WORD PTR [curr_ems_pos+2]
  2969 00001020 A3[6400]                	mov WORD PTR [ovl_empb.es_src_offset+2],ax
  2970 00001023 8916[6800]              	mov WORD PTR [ovl_empb.es_dest_offset],dx
  2971                                  
  2972 00001027 B40B                    	mov ah,0bh				; move extend memory block
  2973 00001029 BE[5C00]                	mov si,OFFSET ovl_empb wrt DGROUP	; ds:si -> parameter block
  2974 0000102C FF1E[0000]              	call	far [xms_addr]
  2975 00001030 E8(0000)                	call	check_xms_error	; see if error occurred
  2976                                  
  2977 00001033 010E[1400]              	add WORD PTR [curr_ems_pos],cx	; adjust for bytes read
  2978 00001037 8316[1600]00            	adc WORD [curr_ems_pos+2],0	; carry to high word
  2979 0000103C 01CA                    	add dx,cx				; update destination offset
  2980 0000103E 83E101                  	and cx,1				; see if extra byte to transfer
  2981 00001041 7410                    	je  xor_ret				; no
  2982 00001043 832E[1400]02            	sub WORD [curr_ems_pos],2	; back up one byte not written, back up one byte for rewrite
  2983 00001048 831E[1600]00            	sbb WORD [curr_ems_pos+2],0	; carry to high word
  2984 0000104D 83EA02                  	sub dx,2				; adjust back one byte, back one for byte not written
  2985 00001050 41                      	inc cx					; two bytes to write
  2986 00001051 EBBD                    	jmp SHORT xor_loop		; write the bytes
  2987                                  
  2988                                  xor_ret:
  2989 00001053 5E                      	pop si					; restore critical register
  2990 00001054 1F                      	pop	ds					; restore ds -> read buffer
  2991 00001055 C3                      	ret
  2992                                  xms_ovl_read    ENDP
  2993                                  
  2994                                  ;*****************************
  2995                                  ;* EMS_OVL_WRITE             *
  2996                                  ;*****************************
  2997                                  
  2998                                  ; write bytes to overlay in EMS at curr_ems_pos
  2999                                  ; ds:dx -> write buffer, cx holds bytes to write
  3000                                  ; do NOT assume ds -> DGROUP upon entry
  3001                                  ; destroys ax,bx,dx
  3002                                  
  3003                                  ems_ovl_write   PROC
  3004 00001056 51                      	push	cx				; save critical register
  3005 00001057 56                      	push	si
  3006 00001058 57                      	push	di
  3007 00001059 06                      	push	es
  3008                                  
  3009 0000105A 8CDB                    	mov bx,ds				; save -> write buffer
  3010 0000105C B8[ssss]                	mov ax,DGROUP
  3011 0000105F 8ED8                    	mov ds,ax				; ds -> warplink data
  3012                                  
  3013 00001061 803E[0200]00            	cmp byte [ovl_in_xms],0		; see if overlay file in XMS
  3014 00001066 7405                    	je  eow_ems				; no, in EMS
  3015 00001068 E86E00                  	call	xms_ovl_write	; write in XMS
  3016 0000106B EB67                    	jmp SHORT eow_ret
  3017                                  
  3018                                  eow_ems:
  3019 0000106D FF36[0000]              	push	WORD [ems_currmap]	; save current logical state of physical page 0
  3020 00001071 53                      	push	bx				; save -> write buffer on stack
  3021                                  
  3022 00001072 89D6                    	mov si,dx				; si -> write buffer
  3023 00001074 8B16[1600]              	mov dx,WORD PTR [curr_ems_pos+2]
  3024 00001078 A1[1400]                	mov ax,WORD PTR [curr_ems_pos]
  3025 0000107B 89C7                    	mov di,ax
  3026 0000107D 81E7FF3F                	and di,16383			; di offsets into EMS page
  3027 00001081 E89FF4                  	call	convert_to_page	; ax holds 16K page of position
  3028                                  
  3029 00001084 010E[1400]              	add WORD PTR [curr_ems_pos],cx	; adjust for bytes written
  3030 00001088 8316[1600]00            	adc WORD [curr_ems_pos+2],0	; carry to high word
  3031 0000108D 0306[1A00]              	add ax,[ems_first_ovl]	; adjust for first page used
  3032                                  
  3033 00001091 89C3                    	mov bx,ax				; bx holds EMS logical page
  3034 00001093 30C0                    	xor al,al
  3035 00001095 E8(0000)                	call	map_ems_page	; map in proper page
  3036                                  
  3037 00001098 8E06[0000]              	mov es,[ems_base]			; es:di -> destination EMS buffer
  3038 0000109C 1F                      	pop ds					; ds:si -> write buffer
  3039                                  
  3040                                  eow_writeloop:
  3041 0000109D 89F8                    	mov ax,di				; check if write to more than one page
  3042 0000109F 01C8                    	add ax,cx
  3043 000010A1 720F                    	jc  eow_offpage			; carry implies write off page
  3044 000010A3 3D0040                  	cmp ax,16384			; check page limit
  3045 000010A6 770A                    	ja  eow_offpage			; off of page
  3046 000010A8 D1E9                    	shr cx,1				; convert byte count to write to words
  3047 000010AA F3A5                    	rep movsw				; move the string
  3048 000010AC D1D1                    	rcl cx,1				; pick up carry
  3049 000010AE F3A4                    	rep movsb				; transfer leftover byte, if any
  3050 000010B0 EB1C                    	jmp SHORT eow_2
  3051                                  
  3052                                  eow_offpage:
  3053 000010B2 B80040                  	mov ax,16384
  3054 000010B5 29F8                    	sub ax,di				; ax holds bytes to write on page
  3055 000010B7 91                      	xchg    ax,cx			; cx holds bytes to write on page, ax holds total bytes
  3056 000010B8 29C8                    	sub ax,cx				; ax holds bytes to write beside current page
  3057 000010BA D1E9                    	shr cx,1				; convert byte count to write to words
  3058 000010BC F3A5                    	rep movsw				; move the string
  3059 000010BE D1D1                    	rcl cx,1				; pick up carry
  3060 000010C0 F3A4                    	rep movsb				; transfer leftover byte, if any
  3061 000010C2 89C1                    	mov cx,ax				; update total bytes to write
  3062 000010C4 31FF                    	xor di,di				; position to start of next page
  3063 000010C6 43                      	inc bx
  3064 000010C7 30C0                    	xor al,al
  3065 000010C9 E8(0000)                	call	map_ems_page	; map in next page
  3066 000010CC EBCF                    	jmp SHORT eow_writeloop	; loop to read more bytes
  3067                                  
  3068                                  eow_2:
  3069 000010CE 5B                      	pop bx					; bx holds previous logical page of EMS page 0
  3070                                  
  3071                                  ; restore previous logical state of EMS physical page 0
  3072 000010CF 30C0                    	xor al,al
  3073 000010D1 E8(0000)                	call	map_ems_page
  3074                                  
  3075                                  eow_ret:
  3076 000010D4 07                      	pop es					; restore critical register
  3077 000010D5 5F                      	pop di
  3078 000010D6 5E                      	pop si
  3079 000010D7 59                      	pop	cx
  3080 000010D8 C3                      	ret
  3081                                  ems_ovl_write   ENDP
  3082                                  
  3083                                  ;*****************************
  3084                                  ;* XMS_OVL_WRITE             *
  3085                                  ;*****************************
  3086                                  
  3087                                  ; write bytes to overlay in EMS at curr_ems_pos
  3088                                  ; bx:dx -> write buffer, cx holds bytes to write
  3089                                  ; ds -> DGROUP upon entry
  3090                                  ; destroys ax,bx,cx,dx,si
  3091                                  
  3092                                  xms_ovl_write   PROC
  3093 000010D9 83F901                  	cmp cx,1				; see if only one byte to write
  3094 000010DC 7457                    	je  xow_1byte			; yes
  3095                                  
  3096 000010DE 31C0                    	xor ax,ax
  3097 000010E0 A3[5E00]                	mov WORD PTR [ovl_empb.es_len+2],ax
  3098 000010E3 A3[6000]                	mov [ovl_empb.es_src_handle],ax	; source is conventional memory
  3099 000010E6 A1[1C00]                	mov ax,[xms_ovl_handle]
  3100 000010E9 A3[6600]                	mov [ovl_empb.es_dest_handle],ax	; destination is XMS memory
  3101                                  
  3102                                  xow_loop:
  3103 000010EC 89C8                    	mov ax,cx
  3104 000010EE 24FE                    	and al,0feh				; round down to word boundary for XMM acceptable length
  3105 000010F0 A3[5C00]                	mov WORD PTR [ovl_empb.es_len],ax	; length of block to transfer low word
  3106 000010F3 8916[6200]              	mov WORD PTR [ovl_empb.es_src_offset],dx
  3107 000010F7 891E[6400]              	mov WORD PTR [ovl_empb.es_src_offset+2],bx
  3108 000010FB A1[1400]                	mov ax,WORD PTR [curr_ems_pos]	; compute destination offset
  3109 000010FE A3[6800]                	mov WORD PTR [ovl_empb.es_dest_offset],ax
  3110 00001101 A1[1600]                	mov ax,WORD PTR [curr_ems_pos+2]
  3111 00001104 A3[6A00]                	mov WORD PTR [ovl_empb.es_dest_offset+2],ax
  3112                                  
  3113 00001107 B40B                    	mov ah,0bh				; move extended memory block
  3114 00001109 BE[5C00]                	mov si,OFFSET ovl_empb wrt DGROUP	; ds:si -> parameter block
  3115 0000110C E84A01                  	call	safe_xms_addr
  3116 0000110F E8(0000)                	call	check_xms_error	; see if error occurred
  3117                                  
  3118 00001112 010E[1400]              	add WORD PTR [curr_ems_pos],cx	; adjust for bytes read
  3119 00001116 8316[1600]00            	adc WORD [curr_ems_pos+2],0	; carry to high word
  3120 0000111B 01CA                    	add dx,cx				; update destination offset
  3121 0000111D 83E101                  	and cx,1				; see if extra byte to transfer
  3122 00001120 7410                    	je  xow_ret				; no
  3123 00001122 832E[1400]02            	sub WORD [curr_ems_pos],2	; back up one byte not written, back up one byte for rewrite
  3124 00001127 831E[1600]00            	sbb WORD [curr_ems_pos+2],0	; carry to high word
  3125 0000112C 83EA02                  	sub dx,2				; adjust back one byte, back one for byte not written
  3126 0000112F 41                      	inc cx					; two bytes to write
  3127 00001130 EBBA                    	jmp SHORT xow_loop		; write the bytes
  3128                                  
  3129                                  xow_ret:
  3130 00001132 8EDB                    	mov ds,bx				; restore ds -> write buffer
  3131 00001134 C3                      	ret
  3132                                  
  3133                                  ; only one byte to write, can't back up to previous
  3134                                  xow_1byte:
  3135 00001135 41                      	inc cx					; make 2 bytes for valid length
  3136 00001136 52                      	push	dx				; save new source pointer offset
  3137 00001137 53                      	push	bx				; save segment
  3138 00001138 BA[1E00]                	mov dx,OFFSET tbuff wrt DGROUP	; ds:dx -> read buffer
  3139 0000113B 8CDB                    	mov bx,ds				; bx -> write buffer
  3140 0000113D E8BCFE                  	call	xms_ovl_read	; get old source byte+following byte in tbuff
  3141 00001140 1F                      	pop ds
  3142 00001141 5B                      	pop bx					; ds:bx -> new source
  3143 00001142 1E                      	push	ds				; save -> original write buffer
  3144 00001143 8A07                    	mov al,[bx]				; get new source byte
  3145 00001145 BB[ssss]                	mov bx,DGROUP			; bx -> warplink data for xms_ovl_write
  3146 00001148 8EDB                    	mov ds,bx				; ds -> warplink data
  3147 0000114A A2[1E00]                	mov BYTE PTR [tbuff],al	; update old source byte to new, following byte stays same
  3148 0000114D BA[1E00]                	mov dx,OFFSET tbuff wrt DGROUP	; ds:dx -> write buffer
  3149 00001150 B90200                  	mov cx,2				; two bytes to write
  3150 00001153 832E[1400]02            	sub WORD [curr_ems_pos],2	; back up two bytes in pseudo-file position
  3151 00001158 831E[1600]00            	sbb WORD [curr_ems_pos+2],0	; borrow to high word
  3152 0000115D E879FF                  	call	xms_ovl_write	; write the buffer
  3153 00001160 1F                      	pop ds					; restore ds -> original write buffer
  3154 00001161 C3                      	ret
  3155                                  
  3156                                  xms_ovl_write   ENDP
  3157                                  
  3158                                  ;*****************************
  3159                                  ;* EMS_OVL_TO_FILE           *
  3160                                  ;*****************************
  3161                                  
  3162                                  ; flush overlays in EMS to overlay file
  3163                                  ; destroys ax,bx,cx,dx,di,si
  3164                                  
  3165                                  ems_ovl_to_file PROC
  3166                                  
  3167                                  ; rewind to start of file
  3168 00001162 8B1E[0000]              	mov bx,[ovl_handle]
  3169 00001166 31C9                    	xor cx,cx
  3170 00001168 89CA                    	mov dx,cx				; zero file offset
  3171 0000116A B80042                  	mov ax,4200h			; move file pointer, absolute offset
  3172 0000116D CD21                    	int 21h
  3173 0000116F E8(0000)                	call	restore_ems_map
  3174                                  
  3175 00001172 803E[0200]00            	cmp byte [ovl_in_xms],0		; see if overlay file in XMS
  3176 00001177 7561                    	jne eot_xms				; yes
  3177                                  
  3178                                  ; read overlay file into EMS
  3179 00001179 FF36[0000]              	push	WORD [ems_currmap]	; save current logical state of physical page 0
  3180 0000117D 8B3E[1A00]              	mov di,[ems_first_ovl]	; di holds first overlay page
  3181                                  
  3182                                  eot_writeloop:
  3183 00001181 30C0                    	xor al,al
  3184 00001183 89FB                    	mov bx,di
  3185 00001185 E8(0000)                	call	map_ems_page
  3186                                  
  3187 00001188 A1[1A00]                	mov ax,WORD PTR [ovl_file_size+2]	; get high word of bytes to write
  3188 0000118B 09C0                    	or  ax,ax				; see if nonzero
  3189 0000118D 750C                    	jne eot_2				; nonzero, write 16K block
  3190 0000118F 8B0E[1800]              	mov cx,WORD PTR [ovl_file_size]	; get low word of bytes to write
  3191 00001193 E33E                    	jcxz    eot_ret			; no bytes to write, done
  3192 00001195 81F90040                	cmp cx,16384			; only write up to 16K
  3193 00001199 7203                    	jb  eot_3				; below 16K
  3194                                  
  3195                                  eot_2:
  3196 0000119B B90040                  	mov cx,16384			; write 16K block
  3197                                  
  3198                                  eot_3:
  3199 0000119E 8B1E[0000]              	mov bx,[ovl_handle]
  3200 000011A2 31D2                    	xor dx,dx
  3201 000011A4 1E                      	push	ds				; save critical register
  3202 000011A5 8E1E[0000]              	mov ds,[ems_base]			; ds:dx -> write buffer, EMS physical page 0
  3203 000011A9 B440                    	mov ah,40h				; write file
  3204 000011AB CD21                    	int 21h
  3205 000011AD E8(0000)                	call	restore_ems_map
  3206 000011B0 1F                      	pop ds					; restore ds -> warplink data
  3207 000011B1 7221                    	jc  eot_doserr			; error occurred
  3208 000011B3 39C8                    	cmp ax, cx
  3209 000011B5 B82700                  	mov ax, 27h			; insufficient disk space error
  3210 000011B8 751A                    	jne eot_doserr
  3211 000011BA 47                      	inc di					; bump to next overlay page
  3212 000011BB 290E[1800]              	sub WORD PTR [ovl_file_size],cx		; subtract off bytes written
  3213 000011BF 831E[1A00]00            	sbb WORD [ovl_file_size+2],0	; borrow to high word
  3214 000011C4 A1[1800]                	mov ax,WORD PTR [ovl_file_size]
  3215 000011C7 0B06[1A00]              	or  ax,WORD PTR [ovl_file_size+2]	; see if written all bytes in overlay file
  3216 000011CB 75B4                    	jne eot_writeloop		; not done yet
  3217                                  
  3218                                  ; restore previous logical state of physical page 0
  3219 000011CD 30C0                    	xor al,al
  3220 000011CF 5B                      	pop bx
  3221 000011D0 E8(0000)                	call	map_ems_page
  3222                                  
  3223                                  eot_ret:
  3224 000011D3 C3                      	ret
  3225                                  
  3226                                  eot_doserr:
  3227 000011D4 BA[0000]                	mov dx,OFFSET ovl_filename wrt DGROUP	; dx -> name of file with error
  3228 000011D7 E9(0000)                	jmp NEAR PTR dos_error	; error opening file
  3229                                  
  3230                                  ; read overlay file from XMS into transfer area, write to file
  3231                                  eot_xms:
  3232 000011DA 31C0                    	xor ax,ax
  3233 000011DC A3[6200]                	mov WORD PTR [ovl_empb.es_src_offset],ax	; zero init the XMS offset in parameter block
  3234 000011DF A3[6400]                	mov WORD PTR [ovl_empb.es_src_offset+2],ax
  3235 000011E2 A3[5E00]                	mov WORD PTR [ovl_empb.es_len+2],ax	; zero high word of block length
  3236 000011E5 A3[6600]                	mov [ovl_empb.es_dest_handle],ax	; zero handle (conventional memory destination)
  3237 000011E8 A3[6800]                	mov WORD PTR [ovl_empb.es_dest_offset],ax	; zero offset
  3238                                  
  3239 000011EB A1[1C00]                	mov ax,[xms_ovl_handle]
  3240 000011EE A3[6000]                	mov [ovl_empb.es_src_handle],ax	; source is XMS
  3241 000011F1 A1[0000]                	mov ax,[ems_trans_block]
  3242 000011F4 A3[6A00]                	mov WORD PTR [ovl_empb.es_dest_offset+2],ax	; destination segment
  3243                                  
  3244                                  eot_xloop:
  3245 000011F7 A1[1A00]                	mov ax,WORD PTR [ovl_file_size+2]	; get high word of bytes to write
  3246 000011FA 09C0                    	or  ax,ax				; see if nonzero
  3247 000011FC 750C                    	jne eot_4				; nonzero, write 16K block
  3248 000011FE 8B0E[1800]              	mov cx,WORD PTR [ovl_file_size]	; get low word of bytes to write
  3249 00001202 E3CF                    	jcxz    eot_ret			; no bytes to write, done
  3250 00001204 81F90040                	cmp cx,16384			; only write up to 16K
  3251 00001208 7203                    	jb  eot_5				; below 16K
  3252                                  
  3253                                  eot_4:
  3254 0000120A B90040                  	mov cx,16384			; write 16K block
  3255                                  
  3256                                  eot_5:
  3257 0000120D 89C8                    	mov ax,cx
  3258 0000120F 40                      	inc ax
  3259 00001210 24FE                    	and al,0feh				; round to word boundary for XMM acceptable length
  3260 00001212 A3[5C00]                	mov WORD PTR [ovl_empb.es_len],ax	; length of block to transfer low word
  3261                                  
  3262 00001215 B40B                    	mov ah,0bh				; move extend memory block
  3263 00001217 BE[5C00]                	mov si,OFFSET ovl_empb wrt DGROUP	; ds:si -> parameter block
  3264 0000121A FF1E[0000]              	call	far [xms_addr]
  3265 0000121E E8(0000)                	call	check_xms_error	; see if error occurred
  3266                                  
  3267 00001221 8B1E[0000]              	mov bx,[ovl_handle]
  3268 00001225 31D2                    	xor dx,dx
  3269 00001227 1E                      	push	ds				; save critical register
  3270 00001228 8E1E[0000]              	mov ds,[ems_trans_block]	; ds:dx -> write buffer
  3271 0000122C B440                    	mov ah,40h				; write file
  3272 0000122E CD21                    	int 21h
  3273 00001230 1F                      	pop ds					; restore ds -> warplink data
  3274 00001231 E8(0000)                	call	restore_ems_map
  3275 00001234 729E                    	jc  eot_doserr			; error writing file
  3276 00001236 39C8                    	cmp ax, cx
  3277 00001238 B82700                  	mov ax, 27h			; insufficient disk space error
  3278 0000123B 7597                    	jne eot_doserr
  3279                                  
  3280 0000123D 010E[6200]              	add WORD PTR [ovl_empb.es_src_offset],cx	; bump dword offset in XMS
  3281 00001241 8316[6400]00            	adc WORD [ovl_empb.es_src_offset+2],0	; carry to high word
  3282 00001246 290E[1800]              	sub WORD PTR [ovl_file_size],cx		; subtract off bytes written
  3283 0000124A 831E[1A00]00            	sbb WORD [ovl_file_size+2],0	; borrow to high word
  3284 0000124F A1[1800]                	mov ax,WORD PTR [ovl_file_size]
  3285 00001252 0B06[1A00]              	or  ax,WORD PTR [ovl_file_size+2]	; see if written all bytes in overlay file
  3286 00001256 759F                    	jne eot_xloop			; not done yet
  3287                                  
  3288 00001258 C3                      	ret
  3289                                  
  3290                                  ems_ovl_to_file ENDP
  3291                                  
  3292                                  ;*****************************
  3293                                  ;* SAFE_XMS_ADDR             *
  3294                                  ;*****************************
  3295                                  
  3296                                  ; save bx and call xms_addr for stupid XMS drivers that eat the bx
  3297                                  ; register but shouldn't
  3298                                  
  3299                                  safe_xms_addr	PROC
  3300 00001259 53                      	push	bx
  3301 0000125A FF1E[0000]              	call	far [xms_addr]
  3302 0000125E 5B                      	pop	bx
  3303 0000125F C3                      	ret
  3304                                  safe_xms_addr	ENDP
  3305                                  
  3306                                  END
