     1                                  ;*********************************************************************
     2                                  ;*   MLPASS2.ASM                                                     *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          07/10/92                                         *
     6                                  ;*   Model:         Small                                            *
     7                                  ;*   Version:       2.5                                              *
     8                                  ;*   Assembler:     MASM 5.0                                         *
     9                                  ;*   Environment:   MS-DOS 2.x+                                      *
    10                                  ;*                                                                   *
    11                                  ;*   linker pass 2 main driver                                       *
    12                                  ;*                                                                   *
    13                                  ;*********************************************************************
    14                                  
    15                                  ;TITLE   WARPLINK mlpass2
    16                                  ;PAGE    50,80
    17                                  
    18                                  ;.MODEL  SMALL
    19                                  
    20                                  ;*****************************
    21                                  ;* Include files             *
    22                                  ;*****************************
    23                                  
    24                                  [list -]
    14                              <1> [list -]
    26                                  [list -]
    31                                       
    32                                  ;*****************************
    33                                  ;* Public declarations       *
    34                                  ;*****************************
    35                                  
    36                                  ; procedures
    37                                  PUBLIC  pass2,get_symbol_offset
    38                                  PUBLIC  no_match_okay
    39                                  
    40                                  ; variables
    41                                  PUBLIC	filesize_text
    42                                  PUBLIC	compression_flag
    43                                  
    44                                  ;*****************************
    45                                  ;* Data begins               *
    46                                  ;*****************************
    47                                  
    48                                  .DATA
    49                                  
    50                                  ;*****************************
    51                                  ;* External declarations     *
    52                                  ;*****************************
    53                                  
    54                                  ; variables
    55                                  EXTRN   data_offset:DWORD
    56                                  EXTRN	ovl_filesize:WORD
    57                                  EXTRN   lookup_segment:WORD,ind_segment:WORD,segcall_segment:WORD
    58                                  EXTRN	is_summer87:BYTE,is_clipper5:BYTE,current_clipmod_ptr:WORD
    59                                  
    60                                  ; initialized local variables
    61                                  
    62                                  ; byte values
    63                                  EVEN
    64 00000000 0000                    no_match_okay: dw 0	; nonzero if no match is okay on public declaration lookup
    65                                  			; used as a word by wlcalc code
    66                                  EVEN
    67                                  
    68                                  ; uninitialized local variables
    69                                  
    70                                  ; byte values
    71 00000002 00                      compression_flag	DB	0	; nonzero if Clipper symbol table compression in force
    72 00000003 00                      EVEN
    73                                  
    74                                  .DATA?
    75                                  EVEN
    76                                  ; word values
    77                                  min_prog_size   LABEL   WORD    ; minimum program size in paragraphs
    77                              <1> min_prog_size :
    78 00000000 ????                    min_alloc_calc  DW  ?       ; largest overlay size in paragraphs rounded to 1K page
    79                                  
    80                                  ;*****************************
    81                                  ;* Constant data             *
    82                                  ;*****************************
    83                                  
    84                                  .CONST
    85                                  
    86                                  EVEN
    87 00000000 24245F4558455F494D-     image_text      DB  '$$_EXE_IMAGE_SIZE',0
    87 00000009 4147455F53495A4500 
    88                                  
    89                                  EVEN
    90                                  
    91                                  %IFNDEF JUNIOR
    92 00000012 24245F4F564C5F4649-     filename_text   DB  '$$_OVL_FILENAME',0
    92 0000001B 4C454E414D4500     
    93 00000022 24245F4F564C5F4C4F-     lookup_text     DB  '$$_OVL_LOOKUP_TABLE',0
    93 0000002B 4F4B55505F5441424C-
    93 00000034 4500               
    94 00000036 24245F4F564C5F494E-     ind_text        DB  '$$_OVL_IND_CALL_TABLE',0
    94 0000003F 445F43414C4C5F5441-
    94 00000048 424C4500           
    95 0000004C 24245F4F564C5F5345-     seg_text        DB  '$$_OVL_SEG_CALL_TABLE',0
    95 00000055 475F43414C4C5F5441-
    95 0000005E 424C4500           
    96 00000062 24245F4F564C5F4D41-     max_text        DB  '$$_OVL_MAX_LOAD',0
    96 0000006B 585F4C4F414400     
    97 00000072 24245F4F564C5F4D45-     mem_text        DB  '$$_OVL_MEM_ALLOC_FLAG',0
    97 0000007B 4D5F414C4C4F435F46-
    97 00000084 4C414700           
    98 00000088 24245F4F564C5F5245-     reload_text     DB  '$$_OVL_RELOAD_FLAG',0
    98 00000091 4C4F41445F464C4147-
    98 0000009A 00                 
    99 0000009B 24245F4F564C5F434C-     clarion_text    DB  '$$_OVL_CLARION_FLAG',0
    99 000000A4 4152494F4E5F464C41-
    99 000000AD 4700               
   100 000000AF 24245F4F564C5F494E-     internal_text   DB  '$$_OVL_INTERNAL_FLAG',0
   100 000000B8 5445524E414C5F464C-
   100 000000C1 414700             
   101 000000C4 24245F4F564C5F4D49-     min_text        DB  '$$_OVL_MIN_ALLOC',0
   101 000000CD 4E5F414C4C4F4300   
   102 000000D5 24245F4F564C5F504F-     pool_text       DB  '$$_OVL_POOL',0
   102 000000DE 4F4C00             
   103 000000E1 24245F4F564C5F5354-     stack_text      DB  '$$_OVL_STACK',0
   103 000000EA 41434B00           
   104 000000EE 24245F4D494E5F5052-     prog_text       DB  '$$_MIN_PROG_SIZE',0
   104 000000F7 4F475F53495A4500   
   105 000000FF 24245F4F564C5F454D-     emspool_text    DB  '$$_OVL_EMS_POOL_FLAG',0
   105 00000108 535F504F4F4C5F464C-
   105 00000111 414700             
   106 00000114 24245F4F564C5F4F58-     ox_text         DB  '$$_OVL_OX_EVAR',0
   106 0000011D 5F4556415200       
   107 00000123 24245F4F564C5F4F52-     ort_text        DB  '$$_OVL_ORT',0
   107 0000012C 5400               
   108 0000012E 24245F4F564C5F4F52-     orp_text        DB  '$$_OVL_ORP',0
   108 00000137 5000               
   109 00000139 24245F4F564C5F4F48-     oht_text		DB	'$$_OVL_OHT',0
   109 00000142 5400               
   110 00000144 24245F4F48545F5349-     oht_size_text	DB	'$$_OHT_SIZE',0
   110 0000014D 5A4500             
   111 00000150 24245F4F48545F464C-     oht_flag_text	DB	'$$_OHT_FLAG',0
   111 00000159 414700             
   112 0000015C 24245F4F564C5F4F48-     ohp_text		DB	'$$_OVL_OHP',0
   112 00000165 5000               
   113 00000167 24245F4F48505F5349-     ohp_size_text	DB	'$$_OHP_SIZE',0
   113 00000170 5A4500             
   114 00000173 24245F4F48505F464C-     ohp_flag_text	DB	'$$_OHP_FLAG',0
   114 0000017C 414700             
   115 0000017F 24245F4F564C5F554D-     umb_text		DB	'$$_OVL_UMB',0
   115 00000188 4200               
   116 0000018A 24245F4F564C5F4649-     filesize_text	DB	'$$_OVL_FILE_SIZE',0
   116 00000193 4C455F53495A4500   
   117 0000019B 24245F454D53335F46-     ems3_text		DB	'$$_EMS3_FLAG',0
   117 000001A4 4C414700           
   118                                  %ENDIF
   119                                  
   120                                  ;*****************************
   121                                  ;* Code begins               *
   122                                  ;*****************************
   123                                  
   124                                  .CODE
   125                                  
   126                                  ;*****************************
   127                                  ;* External declarations     *
   128                                  ;*****************************
   129                                  
   130                                  ; procedures
   131                                  EXTRN   perform_pass:NEAR,find_pubdecl_entry:NEAR
   132                                  EXTRN   link_error:NEAR,write_bytes:NEAR
   133                                  
   134                                  ; main driver for pass 2 of linker
   135                                  ; all registers used or destroyed
   136                                  
   137                                  ;*****************************
   138                                  ;* PASS2                     *
   139                                  ;*****************************
   140                                  
   141                                  pass2       PROC
   142 00000000 31C0                    	xor	ax,ax
   143 00000002 3806[0000]              	cmp	[is_sympac],al		; check if symbol table compression
   144 00000006 740F                    	je	p2_dosseg			; no
   145 00000008 A0[0000]                	mov	al,[is_summer87]
   146 0000000B 0A06[0000]              	or	al,[is_clipper5]
   147 0000000F A2[0200]                	mov	[compression_flag],al	; set symbol table compression flag if indicated
   148 00000012 31C0                    	xor	ax,ax
   149 00000014 A3[0000]                	mov	[current_clipmod_ptr],ax	; init current clipper module pointer
   150                                  
   151                                  p2_dosseg:
   152 00000017 3806[0000]                  cmp [is_dosseg],al        ; see if dosseg switch set
   153 0000001B 7403                        je  p2                  ; no
   154 0000001D E88400                      call    resolve_symbols ; resolve _edata and _end symbols
   155                                  
   156                                  p2:
   157 00000020 B002                        mov al,2                ; flag pass 2
   158 00000022 E8(0000)                    call    perform_pass    ; perform pass functions, al flags pass 2 specific routines
   159                                  
   160                                  %IFNDEF JUNIOR
   161 00000025 31C0                        xor ax,ax
   162 00000027 3906[0000]                  cmp [ovl_count],ax        ; see if any overlays
   163 0000002B 7409                        je  p3                  ; no
   164 0000002D A3[0000]                    mov [ovl_code_id],ax      ; zero overlay code so writes to exe and not ovl file
   165 00000030 A3[0000]                    mov [ovl_data_id],ax      ; zero overlaid data flag
   166 00000033 E8B400                      call    res_ovl_symbols ; resolve symbols for overlay manager
   167                                  
   168                                  p3:
   169 00000036 803E[0000]00                cmp byte [is_comfile],0        ; see if com file
   170 0000003B 7503                    	jne @F			; yes, don't add information symbols
   171 0000003D E80D00                      call    res_info_symbols    ; resolve warplink information symbols
   172                                  @@:
   173                                  %ENDIF
   174                                  
   175 00000040 D006[0000]              	rol byte [is_wlcalc_enabled], 1
   176 00000044 7306                    	jnc @F
   177                                    extern patch_wlcalc_sites
   178 00000046 B80100                  	mov ax, 1
   179 00000049 E8(0000)                	call patch_wlcalc_sites
   180                                  @@:
   181 0000004C C3                          ret
   182                                  pass2       ENDP
   183                                  
   184                                  %IFNDEF JUNIOR
   185                                  
   186                                  ;*****************************
   187                                  ;* RES_INFO_SYMBOLS          *
   188                                  ;*****************************
   189                                  
   190                                  ; resolve $$_EXE_IMAGE_SIZE variable if exists, fill with image_size
   191                                  ; destroys ax,bx,cx,dx,di,es
   192                                  
   193                                  res_info_symbols    PROC
   194 0000004D C606[0000]01                mov byte [no_match_okay],1     ; set flag that no matches in public search are okay
   195                                  
   196                                  ; write exe image size double word if predefined
   197 00000052 BF[0000]                    mov di,OFFSET image_text wrt DGROUP
   198 00000055 E8(0000)                    call    find_pubdecl_entry  ; find the symbol
   199 00000058 09C0                        or  ax,ax               ; make sure nonzero
   200 0000005A 7442                        je  ris_ret             ; not found
   201                                  
   202                                  ; get offset from start of program in cx:dx
   203 0000005C 31C9                        xor cx,cx               ; zero high word
   204 0000005E 8EC0                        mov es,ax               ; es -> public declaration entry
   205 00000060 26A00E00                    mov al,[es:14]          ; get definition flag
   206 00000064 2403                        and al,3
   207 00000066 3C02                        cmp al,2                ; make sure publicly declared
   208 00000068 7534                        jne ris_ret             ; no, don't use it
   209                                  
   210 0000006A 268B160800                  mov dx,[es:8]           ; get public offset
   211 0000006F 268E060000                  mov es,[es:0]           ; es -> segment partition entry
   212 00000074 2603160000                  add dx,[es:0]           ; add in segment partition offset
   213 00000079 83D100                      adc cx,0                ; carry to high word
   214 0000007C 268E060400                  mov es,[es:4]           ; es -> master segdef entry
   215                                  
   216 00000081 2603160200                  add dx,[es:2]           ; add in low word
   217 00000086 26130E0400                  adc cx,[es:4]           ; add in high word
   218 0000008B 8916[0000]                  mov WORD PTR [data_offset],dx ; save low word
   219 0000008F 890E[0200]                  mov WORD PTR [data_offset+2],cx   ; save high word
   220                                  
   221 00000093 BE[0000]                    mov si,OFFSET image_size wrt DGROUP
   222 00000096 1E                      	push	ds
   223 00000097 07                      	pop	es					; es:si -> source buffer
   224                                  
   225 00000098 B90400                      mov cx,4                ; write one doubleword
   226 0000009B E8(0000)                    call    write_bytes
   227                                  
   228                                  ris_ret:
   229 0000009E C606[0000]00                mov byte [no_match_okay],0     ; done, reset flag so remaining no matches generate internal errors
   230 000000A3 C3                          ret
   231                                  res_info_symbols    ENDP
   232                                  
   233                                  %ENDIF
   234                                  
   235                                  ;*****************************
   236                                  ;* RESOLVE_SYMBOLS           *
   237                                  ;*****************************
   238                                  
   239                                  ; resolve _edata and _end symbols
   240                                  ; destroys ax,bx,dx,es
   241                                  
   242                                  resolve_symbols PROC
   243 000000A4 A1[0000]                    mov ax,[_edata_pubaddr]   ; get segment of _edata public declaration entry
   244 000000A7 8EC0                        mov es,ax               ; es -> pubdef declaration
   245 000000A9 A1[0000]                    mov ax,[_edata_segaddr]   ; get segment of first class BSS segment segdef entry
   246 000000AC 09C0                        or  ax,ax               ; check if nonzero
   247 000000AE 7506                        jne rs_2                ; yes
   248 000000B0 26C6060E0001                mov BYTE PTR [es:14],1  ; make it an unresolved external
   249                                  
   250                                  rs_2:
   251 000000B6 E81200                      call    NEAR PTR rs_3   ; sleazy way to save code, end of routine shares same code
   252                                  
   253 000000B9 A1[0000]                    mov ax,[_end_pubaddr]     ; get segment of _edata public declaration entry
   254 000000BC 8EC0                        mov es,ax               ; es -> pubdef declaration
   255 000000BE A1[0000]                    mov ax,[_end_segaddr]     ; get segment of first class BSS segment segdef entry
   256 000000C1 09C0                        or  ax,ax               ; check if nonzero
   257 000000C3 7506                        jne rs_3                ; yes
   258 000000C5 26C6060E0001                mov BYTE PTR [es:14],1  ; make it an unresolved external
   259                                  
   260                                  rs_3:
   261 000000CB 8CC3                        mov bx,es               ; save es -> pubdef declaration
   262 000000CD 8EC0                        mov es,ax               ; es -> segdef entry
   263 000000CF 26A11600                    mov ax,[es:22]          ; get first segment partition entry pointer
   264 000000D3 268B161000                  mov dx,[es:16]          ; get pointer to group entry
   265 000000D8 8EC3                        mov es,bx               ; es -> pubdef declaration
   266 000000DA 26A30000                    mov [es:0],ax           ; update segdef partition entry pointer in public declaration entry
   267 000000DE 2689160200                  mov [es:2],dx           ; update group entry pointer
   268 000000E3 26C6060F0080                mov BYTE PTR [es:15],80h    ; show group associated with public declaration
   269 000000E9 C3                          ret
   270                                  resolve_symbols ENDP
   271                                  
   272                                  %IFNDEF JUNIOR
   273                                  
   274                                  ;*****************************
   275                                  ;* RES_OVL_SYMBOLS           *
   276                                  ;*****************************
   277                                  
   278                                  ; resolve overlay symbols
   279                                  ; $$_OVL_FILENAME from ovl_nopath byte string OR
   280                                  ; from exe_name if internal overlays flag set
   281                                  ; $$_OVL_LOOKUP_TABLE from lookup_segment word
   282                                  ; $$_OVL_IND_CALL_TABLE from ind_segment word
   283                                  ; $$_OVL_SEG_CALL_TABLE from segcall_segment word
   284                                  ; $$_OVL_MAX_LOAD from ovl_max_load word
   285                                  ; $$_OVL_MEM_ALLOC_FLAG from ovl_mem_alloc byte
   286                                  ; $$_OVL_RELOAD_FLAG from is_reload byte
   287                                  ; $$_OVL_CLARION_FLAG from is_clarion byte
   288                                  ; $$_OVL_INTERNAL_FLAG from is_internal byte
   289                                  ; $$_OVL_MIN_ALLOC from largest_ovl word
   290                                  ; $$_OVL_POOL from ovl_pool doubleword
   291                                  ; $$_OVL_STACK from ovl_stack word
   292                                  ; $$_MIN_PROG_SIZE from image_size
   293                                  ; $$_OVL_EMS_POOL_FLAG from is_ems_ovlpool
   294                                  ; destroys ax,bx,cx,dx,di,es
   295                                  
   296                                  res_ovl_symbols PROC
   297 000000EA C606[0000]01                mov byte [no_match_okay],1     ; set flag that no matches in public search are okay
   298                                  
   299                                  ; write filename bytes (no path prepended)
   300 000000EF BF[1200]                    mov di,OFFSET filename_text wrt DGROUP
   301 000000F2 E8F801                      call    get_symbol_offset
   302 000000F5 BE[0000]                    mov si,OFFSET ovl_nopath wrt DGROUP ; es:si -> buffer
   303 000000F8 803E[0000]00                cmp byte [is_internal],0       ; see if internal overlay flag set
   304 000000FD 7422                        je  sym_loop1           ; no
   305                                  
   306                                  ; internal overlay flag set, use EXE name for OVL name
   307 000000FF BE[0000]                    mov si,OFFSET exe_name wrt DGROUP
   308 00000102 31C9                        xor cx,cx               ; cx will hold count of chars in name, including terminator
   309                                  
   310                                  ros_loop:
   311 00000104 AC                          lodsb
   312 00000105 41                          inc cx                  ; bump count of chars in name
   313 00000106 08C0                        or  al,al               ; see if zero terminator reached
   314 00000108 75FA                        jne ros_loop            ; no
   315                                  
   316                                  ros_loop2:
   317 0000010A 4E                          dec si                  ; back up one char
   318 0000010B 49                          dec cx                  ; drop count of chars to scan back
   319 0000010C E313                        jcxz    sym_loop1       ; at beginning of name, use it all
   320 0000010E 803C3A                      cmp BYTE PTR [si],':'   ; see if possible drive specifier
   321 00000111 7508                        jne ros_2               ; no
   322 00000113 89F0                        mov ax,si
   323 00000115 48                          dec ax
   324 00000116 3D[0000]                    cmp ax,OFFSET exe_name wrt DGROUP   ; drive specifier if and only if ':' second char in name
   325 00000119 7405                        je  ros_3               ; drive specifier
   326                                  
   327                                  ros_2:
   328 0000011B 803C5C                      cmp BYTE PTR [si],'\'   ; see if backed up to directory indicator
   329 0000011E 75EA                        jne ros_loop2           ; no
   330                                  
   331                                  ros_3:
   332 00000120 46                          inc si                  ; point just past directory indicator or drive specifier
   333                                  
   334                                  sym_loop1:
   335 00000121 B90100                      mov cx,1                ; write one byte
   336 00000124 E8(0000)                    call    write_bytes
   337 00000127 8306[0000]01                add WORD [data_offset],1
   338 0000012C 8316[0200]00                adc WORD [data_offset+2],0    ; increment the data_offset variable
   339 00000131 807CFF00                    cmp BYTE PTR [si-1],0   ; see if null terminator written
   340 00000135 75EA                        jne sym_loop1           ; no
   341                                  
   342                                  ; write lookup table segment
   343 00000137 BF[2200]                    mov di,OFFSET lookup_text wrt DGROUP
   344 0000013A E8B001                      call    get_symbol_offset
   345 0000013D BE[0000]                    mov si,OFFSET lookup_segment wrt DGROUP ; es:si -> buffer
   346 00000140 B90200                      mov cx,2                ; write one word
   347 00000143 E8(0000)                    call    write_bytes
   348                                  
   349                                  ; write indirect call table segment
   350 00000146 BF[3600]                    mov di,OFFSET ind_text wrt DGROUP
   351 00000149 E8A101                      call    get_symbol_offset
   352 0000014C BE[0000]                    mov si,OFFSET ind_segment wrt DGROUP    ; es:si -> buffer
   353 0000014F B90200                      mov cx,2                ; write one word
   354 00000152 E8(0000)                    call    write_bytes
   355                                  
   356                                  ; write segment call table segment
   357 00000155 BF[4C00]                    mov di,OFFSET seg_text wrt DGROUP
   358 00000158 E89201                      call    get_symbol_offset
   359 0000015B BE[0000]                    mov si,OFFSET segcall_segment wrt DGROUP    ; es:si -> buffer
   360 0000015E B90200                      mov cx,2                ; write one word
   361 00000161 E8(0000)                    call    write_bytes
   362                                  
   363                                  ; write maximum overlays loaded word
   364 00000164 BF[6200]                    mov di,OFFSET max_text wrt DGROUP
   365 00000167 E88301                      call    get_symbol_offset
   366 0000016A BE[0000]                    mov si,OFFSET ovl_max_load wrt DGROUP   ; es:si -> buffer
   367 0000016D B90200                      mov cx,2                ; write one word
   368 00000170 E8(0000)                    call    write_bytes
   369                                  
   370                                  ; write minimum program size in paragraphs word
   371 00000173 BF[EE00]                    mov di,OFFSET prog_text wrt DGROUP
   372 00000176 E87401                      call    get_symbol_offset
   373 00000179 BE[0000]                    mov si,OFFSET min_prog_size wrt DGROUP  ; es:si -> buffer
   374                                  
   375                                  ; calculate minimum program size in paragraphs
   376 0000017C A1[0000]                    mov ax,WORD PTR [image_size]  ; get low word of program size
   377 0000017F 8B1E[0200]                  mov bx,WORD PTR [image_size+2]    ; get high word
   378 00000183 83C00F                      add ax,15               ; round up to paragraph
   379 00000186 83D300                      adc bx,0
   380 00000189 D1EB                        shr bx,1
   381 0000018B D1D8                        rcr ax,1                ; /2, convert to paragraphs
   382 0000018D D1EB                        shr bx,1
   383 0000018F D1D8                        rcr ax,1                ; /4
   384 00000191 D1EB                        shr bx,1
   385 00000193 D1D8                        rcr ax,1                ; /8
   386 00000195 D1EB                        shr bx,1
   387 00000197 D1D8                        rcr ax,1                ; /16
   388 00000199 8904                        mov [si],ax             ; save to memory variable
   389 0000019B B90200                      mov cx,2                ; write one word
   390 0000019E E8(0000)                    call    write_bytes
   391                                  
   392                                  ; write memory allocation flag byte
   393 000001A1 BF[7200]                    mov di,OFFSET mem_text wrt DGROUP
   394 000001A4 E84601                      call    get_symbol_offset
   395 000001A7 BE[0000]                    mov si,OFFSET ovl_mem_alloc wrt DGROUP  ; es:si -> buffer
   396 000001AA B90100                      mov cx,1                ; write one byte
   397 000001AD E8(0000)                    call    write_bytes
   398                                  
   399                                  ; write reload overlay flag byte
   400 000001B0 BF[8800]                    mov di,OFFSET reload_text wrt DGROUP
   401 000001B3 E83701                      call    get_symbol_offset
   402 000001B6 BE[0000]                    mov si,OFFSET is_reload wrt DGROUP  ; es:si -> buffer
   403 000001B9 B90100                      mov cx,1                ; write one byte
   404 000001BC E8(0000)                    call    write_bytes
   405                                  
   406                                  ; write clarion flag byte
   407 000001BF BF[9B00]                    mov di,OFFSET clarion_text wrt DGROUP
   408 000001C2 E82801                      call    get_symbol_offset
   409 000001C5 BE[0000]                    mov si,OFFSET is_clarion wrt DGROUP ; es:si -> buffer
   410 000001C8 B90100                      mov cx,1                ; write one byte
   411 000001CB E8(0000)                    call    write_bytes
   412                                  
   413                                  ; write internal overlays flag byte
   414 000001CE BF[AF00]                    mov di,OFFSET internal_text wrt DGROUP
   415 000001D1 E81901                      call    get_symbol_offset
   416 000001D4 BE[0000]                    mov si,OFFSET is_internal wrt DGROUP    ; es:si -> buffer
   417 000001D7 B90100                      mov cx,1                ; write one byte
   418 000001DA E8(0000)                    call    write_bytes
   419                                  
   420                                  ; write EMS overlay pool flag byte
   421 000001DD BF[FF00]                    mov di,OFFSET emspool_text wrt DGROUP
   422 000001E0 E80A01                      call    get_symbol_offset
   423 000001E3 BE[0000]                    mov si,OFFSET is_ems_ovlpool wrt DGROUP ; es:si -> buffer
   424 000001E6 B90100                      mov cx,1                ; write one byte
   425 000001E9 E8(0000)                    call    write_bytes
   426                                  
   427                                  ; write EMS 4.0 overlay stash byte
   428 000001EC BF[2E01]                    mov di,OFFSET orp_text wrt DGROUP
   429 000001EF E8FB00                      call    get_symbol_offset
   430 000001F2 BE[0000]                    mov si,OFFSET is_xpstash wrt DGROUP ; es:si -> buffer
   431 000001F5 B90100                      mov cx,1                ; write one byte
   432 000001F8 E8(0000)                    call    write_bytes
   433                                  
   434                                  ; write XMS overlay stash byte
   435 000001FB BF[2301]                    mov di,OFFSET ort_text wrt DGROUP
   436 000001FE E8EC00                      call    get_symbol_offset
   437 00000201 BE[0000]                    mov si,OFFSET is_xtstash wrt DGROUP ; es:si -> buffer
   438 00000204 B90100                      mov cx,1                ; write one byte
   439 00000207 E8(0000)                    call    write_bytes
   440                                  
   441                                  ; write /ohp setting byte
   442 0000020A BF[5C01]                    mov di,OFFSET ohp_text wrt DGROUP
   443 0000020D E8DD00                      call    get_symbol_offset
   444 00000210 BE[0000]                    mov si,OFFSET is_ohp wrt DGROUP	; es:si -> buffer
   445 00000213 B90100                      mov cx,1                ; write one byte
   446 00000216 E8(0000)                    call    write_bytes
   447                                  
   448                                  ; write /ohp allocation byte
   449 00000219 BF[7301]                    mov di,OFFSET ohp_flag_text wrt DGROUP
   450 0000021C E8CE00                      call    get_symbol_offset
   451 0000021F BE[0000]                    mov si,OFFSET ovl_ohp_alloc wrt DGROUP	; es:si -> buffer
   452 00000222 B90100                      mov cx,1                ; write one byte
   453 00000225 E8(0000)                    call    write_bytes
   454                                  
   455                                  ; write /ohp size word
   456 00000228 BF[6701]                    mov di,OFFSET ohp_size_text wrt DGROUP
   457 0000022B E8BF00                      call    get_symbol_offset
   458 0000022E BE[0000]                    mov si,OFFSET ovl_ohp_size wrt DGROUP	; es:si -> buffer
   459 00000231 B90200                      mov cx,2                ; write one word
   460 00000234 E8(0000)                    call    write_bytes
   461                                  
   462                                  ; write /oht setting byte
   463 00000237 BF[3901]                    mov di,OFFSET oht_text wrt DGROUP
   464 0000023A E8B000                      call    get_symbol_offset
   465 0000023D BE[0000]                    mov si,OFFSET is_oht wrt DGROUP	; es:si -> buffer
   466 00000240 B90100                      mov cx,1                ; write one byte
   467 00000243 E8(0000)                    call    write_bytes
   468                                  
   469                                  ; write /oht allocation byte
   470 00000246 BF[5001]                    mov di,OFFSET oht_flag_text wrt DGROUP
   471 00000249 E8A100                      call    get_symbol_offset
   472 0000024C BE[0000]                    mov si,OFFSET ovl_oht_alloc wrt DGROUP	; es:si -> buffer
   473 0000024F B90100                      mov cx,1                ; write one byte
   474 00000252 E8(0000)                    call    write_bytes
   475                                  
   476                                  ; write /oht size word
   477 00000255 BF[4401]                    mov di,OFFSET oht_size_text wrt DGROUP
   478 00000258 E89200                      call    get_symbol_offset
   479 0000025B BE[0000]                    mov si,OFFSET ovl_oht_size wrt DGROUP	; es:si -> buffer
   480 0000025E B90200                      mov cx,2                ; write one word
   481 00000261 E8(0000)                    call    write_bytes
   482                                  
   483                                  ; write UMB overlay pool byte
   484 00000264 BF[7F01]                    mov di,OFFSET umb_text wrt DGROUP
   485 00000267 E88300                      call    get_symbol_offset
   486 0000026A BE[0000]                    mov si,OFFSET is_umb wrt DGROUP	; es:si -> buffer
   487 0000026D B90100                      mov cx,1                ; write one byte
   488 00000270 E8(0000)                    call    write_bytes
   489                                  
   490                                  ; write EMS 3.0 compatibility byte
   491 00000273 BF[9B01]                    mov di,OFFSET ems3_text wrt DGROUP
   492 00000276 E87400                      call    get_symbol_offset
   493 00000279 BE[0000]                    mov si,OFFSET ems3_flag wrt DGROUP	; es:si -> buffer
   494 0000027C B90100                      mov cx,1                ; write one byte
   495 0000027F E8(0000)                    call    write_bytes
   496                                  
   497                                  ; write overlay file size word
   498 00000282 BF[8A01]                    mov di,OFFSET filesize_text wrt DGROUP
   499 00000285 E86500                      call    get_symbol_offset
   500 00000288 BE[0000]                    mov si,OFFSET ovl_filesize wrt DGROUP	; es:si -> buffer
   501 0000028B B90200                      mov cx,2                ; write one word
   502 0000028E E8(0000)                    call    write_bytes
   503                                  
   504                                  ; write EMS /ox environment variable
   505 00000291 BF[1401]                    mov di,OFFSET ox_text wrt DGROUP
   506 00000294 E85600                      call    get_symbol_offset
   507 00000297 BE[0000]                    mov si,OFFSET ovl_ox_evar wrt DGROUP    ; es:si -> buffer
   508 0000029A B92000                      mov cx,32               ; write 32 bytes
   509 0000029D E8(0000)                    call    write_bytes
   510                                  
   511                                  ; write minimum allocation word
   512 000002A0 BF[C400]                    mov di,OFFSET min_text wrt DGROUP
   513 000002A3 E84700                      call    get_symbol_offset
   514 000002A6 BE[0000]                    mov si,OFFSET min_alloc_calc wrt DGROUP ; es:si -> buffer
   515                                  
   516                                  ; calculate minimum allocation in paragraphs, rounded to 1K page
   517 000002A9 A1[0000]                    mov ax,[largest_ovl]      ; get size of largest overlay in bytes
   518 000002AC 05FF03                      add ax,1023             ; round up to next 1K boundary
   519 000002AF 7305                        jnc sym_2               ; no overflow
   520 000002B1 B80010                      mov ax,1000h            ; 64K segment paragraph size
   521 000002B4 EB0D                        jmp SHORT sym_3         ; bypass segment paragraph size calculation
   522                                  
   523                                  sym_2:
   524 000002B6 2500FC                      and ax,0fc00h           ; put on 1K boundary
   525 000002B9 D1E8                        shr ax,1
   526 000002BB D1E8                        shr ax,1
   527 000002BD D1E8                        shr ax,1
   528 000002BF D1E8                        shr ax,1                ;  ax holds paragraph value of overlay, rounded to 1K boundary
   529 000002C1 8904                        mov [si],ax             ; save to memory variable
   530                                  
   531                                  sym_3:
   532 000002C3 B90200                      mov cx,2                ; write one word
   533 000002C6 E8(0000)                    call    write_bytes
   534                                  
   535                                  ; write overlay pool doubleword
   536 000002C9 BF[D500]                    mov di,OFFSET pool_text wrt DGROUP
   537 000002CC E81E00                      call    get_symbol_offset
   538 000002CF BE[0000]                    mov si,OFFSET ovl_pool wrt DGROUP   ; es:si -> buffer
   539 000002D2 B90400                      mov cx,4                ; write one doubleword
   540 000002D5 E8(0000)                    call    write_bytes
   541                                  
   542                                  ; write overlay stack size word
   543 000002D8 BF[E100]                    mov di,OFFSET stack_text wrt DGROUP
   544 000002DB E80F00                      call    get_symbol_offset
   545 000002DE BE[0000]                    mov si,OFFSET ovl_stack wrt DGROUP  ; es:si -> buffer
   546 000002E1 B90200                      mov cx,2                ; write one word
   547 000002E4 E8(0000)                    call    write_bytes
   548                                  
   549 000002E7 C606[0000]00                mov byte [no_match_okay],0     ; done, reset flag so remaining no matches generate internal errors
   550 000002EC C3                          ret
   551                                  
   552                                  res_ovl_symbols ENDP
   553                                  
   554                                  ;*****************************
   555                                  ;* GET_SYMBOL_OFFSET         *
   556                                  ;*****************************
   557                                  
   558                                  ; get symbol's absolute offset in program
   559                                  ; return offset in data_offset and es -> WarpLink data segment
   560                                  ; ds:di -> symbol name upon entry
   561                                  ; destroys ax,bx,cx,dx,es
   562                                  
   563                                  get_symbol_offset   PROC
   564 000002ED E8(0000)                    call    find_pubdecl_entry  ; find the symbol
   565 000002F0 09C0                        or  ax,ax               ; make sure nonzero
   566 000002F2 7430                        je  no_ovl_mgr          ; not found, assume overlay manager wasn't linked in
   567                                  
   568                                  ; get offset from start of program in cx:dx
   569 000002F4 31C9                        xor cx,cx               ; zero high word
   570 000002F6 8EC0                        mov es,ax               ; es -> public declaration entry
   571 000002F8 268B160800                  mov dx,[es:8]           ; get public offset
   572 000002FD 268E060000                  mov es,[es:0]           ; es -> segment partition entry
   573 00000302 2603160000                  add dx,[es:0]           ; add in segment partition offset
   574 00000307 83D100                      adc cx,0                ; carry to high word
   575 0000030A 268E060400                  mov es,[es:4]           ; es -> master segdef entry
   576 0000030F 2603160200                  add dx,[es:2]           ; add in low word
   577 00000314 26130E0400                  adc cx,[es:4]           ; add in high word
   578 00000319 8916[0000]                  mov WORD PTR [data_offset],dx ; save low word
   579 0000031D 890E[0200]                  mov WORD PTR [data_offset+2],cx   ; save high word
   580 00000321 1E                      	push	ds
   581 00000322 07                      	pop	es
   582 00000323 C3                          ret
   583                                  
   584                                  ; overlay manager not linked in, fatal error
   585                                  no_ovl_mgr:
   586 00000324 B84100                      mov ax,MISSING_OVLMGR_ERR
   587 00000327 E9(0000)                    jmp NEAR PTR link_error
   588                                  
   589                                  get_symbol_offset   ENDP
   590                                  
   591                                  %ENDIF
   592                                  
   593                                  END
