     1                                  ;*********************************************************************
     2                                  ;*   MLOVLRES.ASM                                                    *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          12/22/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 mlovlres
    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  resolve_ovl_info,ovl_entry_point,fixup_ovl_extdef
    36                                  PUBLIC  fixup_ind_ref_extdef,fixup_seg_ref,make_master_segblk
    37                                  
    38                                  ;*****************************
    39                                  ;* Data begins               *
    40                                  ;*****************************
    41                                  
    42                                  .DATA
    43                                  
    44                                  ;*****************************
    45                                  ;* External declarations     *
    46                                  ;*****************************
    47                                  
    48                                  ; variables
    49                                  EXTRN   ovlpubblk_pos:WORD,loc:BYTE,target_prog_off:DWORD
    50                                  EXTRN   ovl_pub_seg_ptr:DWORD,data_seg_part:WORD
    51                                  EXTRN   data_offset:DWORD,locat:WORD,ind_segment:WORD,segcall_segment:WORD
    52                                  EXTRN   seg_ovl_class_flag:BYTE,is_ind_call:BYTE
    53                                  EXTRN   target_segment:WORD,is_relocatable:BYTE
    54                                  EXTRN   target_disp:DWORD,data_rec_offset:WORD
    55                                  EXTRN   large_ovl_name:DWORD
    56                                  EXTRN   frame_method:BYTE,filename:BYTE
    57                                  EXTRN   no_fixbyte_flag:BYTE,gen_flags:BYTE
    58                                  EXTRN   fixup_pos:WORD
    59                                  
    60                                  ; initialized local variables
    61                                  
    62                                  ; byte values
    63 00000000 2030304B20              tbuff   DB  ' 00K '          ; buffer for minimum overlay allocation feedback
    64 00000005 28                      left_paren  DB  '('
    65 00000006 290D0A                  right_paren DB  ')',CR,LF
    66                                  
    67                                  .DATA?
    68                                  
    69                                  EVEN
    70                                  
    71                                  ; uninitialized local variables
    72 00000000 ????                    curseg_ptr  DW  ?           ; pointer to current segment in overlaid public block
    73 00000002 ????                    curblk_ptr  DW  ?           ; pointer to block for which curseg_ptr is valid
    74 00000004 ????                    mainovl_offval  DW  ?       ; main overlay vector entry address offset
    75 00000006 ????                    mainovl_segval  DW  ?       ; main overlay vector entry address segment
    76                                  
    77                                  ;*****************************
    78                                  ;* Constant data             *
    79                                  ;*****************************
    80                                  
    81                                  .CONST
    82                                  
    83 00000000 46                      maxtext_len     DB  maxtext_stop-max_text
    84 00000001 0D0A4D696E696D756D-     max_text        DB  CR,LF,'Minimum overlay allocation exceeds maximum pool size, size adjusted.'
    84 0000000A 206F7665726C617920-
    84 00000013 616C6C6F636174696F-
    84 0000001C 6E2065786365656473-
    84 00000025 206D6178696D756D20-
    84 0000002E 706F6F6C2073697A65-
    84 00000037 2C2073697A65206164-
    84 00000040 6A75737465642E     
    85                                  maxtext_stop    equ   $
    86                                  
    87 00000047 26                      mintext_len     DB  mintext_stop-min_text
    88 00000048 0D0A4D696E696D756D-     min_text        DB  CR,LF,'Minimum allowed overlay allocation: '
    88 00000051 20616C6C6F77656420-
    88 0000005A 6F7665726C61792061-
    88 00000063 6C6C6F636174696F6E-
    88 0000006C 3A20               
    89                                  mintext_stop    equ   $
    90                                  
    91 0000006E 1F                      rectext_len     DB  rectext_stop-rec_text
    92 0000006F 526571756972656420-     rec_text        DB  'Required minimum for /r usage: '
    92 00000078 6D696E696D756D2066-
    92 00000081 6F72202F7220757361-
    92 0000008A 67653A20           
    93                                  rectext_stop    equ   $
    94                                  
    95 0000008E 24                      clartext_len    DB  clartext_stop-clar_text
    96 0000008F 526571756972656420-     clar_text       DB  'Required minimum for Clarion usage: '
    96 00000098 6D696E696D756D2066-
    96 000000A1 6F7220436C6172696F-
    96 000000AA 6E2075736167653A20 
    97                                  clartext_stop   equ   $
    98                                  
    99 000000B3 24245F4F564C5F494E-     entry_text      DB  '$$_OVL_INIT_ENTRY',0
    99 000000BC 49545F454E54525900 
   100 000000C5 24245F4F564C5F5645-     main_text       DB  '$$_OVL_VECTOR',0
   100 000000CE 43544F5200         
   101                                  
   102                                  ;*****************************
   103                                  ;* Code begins               *
   104                                  ;*****************************
   105                                  
   106                                  .CODE
   107                                  
   108                                  ;*****************************
   109                                  ;* External declarations     *
   110                                  ;*****************************
   111                                  
   112                                  EXTRN   link_error:NEAR,dos_error:NEAR,alloc_memory:NEAR
   113                                  EXTRN   setup_ovl_file:NEAR,link_warning:NEAR
   114                                  EXTRN   make_segdef_blk:NEAR,init_segdef_entry:NEAR
   115                                  EXTRN   find_pubdecl_entry:NEAR,get_symbol_segoff:NEAR
   116                                  EXTRN   restore_ems_map:NEAR
   117                                  
   118                                  ;*****************************
   119                                  ;* RESOLVE_OVL_INFO          *
   120                                  ;*****************************
   121                                  
   122                                  ; resolve overlay information, set up for second pass
   123                                  ; destroys ax,bx,cx,dx,di,bp,si,es
   124                                  
   125                                  resolve_ovl_info    PROC
   126 00000000 31D2                        xor dx,dx               ; init overlaid public count after check for overlay class
   127 00000002 31ED                        xor bp,bp               ; init far reference count after check
   128 00000004 A1[0000]                    mov ax,[first_ovlpubblk_ptr]  ; get first allocate overlaid public block
   129 00000007 BB0200                      mov bx,2                ; init block position
   130 0000000A 8EC0                        mov es,ax               ; es -> public block
   131 0000000C E9CB00                      jmp NEAR PTR res_blk_chk2   ; bypass previous segment entry update
   132                                  
   133                                  ; no more overlaid publics for this segment, move to next, if any
   134                                  ; update length of previous segment (dx*7 bytes),
   135                                  ; nonoverlaid segment partition updates segdef entry length
   136                                  ; overlay updates segment partition entry length
   137                                  ; set si to segment partition, re-init cx,dx counters
   138                                  res_seg_done:
   139 0000000F 8B3E[0000]                  mov di,[curseg_ptr]       ; get pointer to current segment value
   140 00000013 83C702                      add di,2                ; bump to near references count
   141 00000016 06                          push    es              ; save -> current overlaid public block on stack
   142 00000017 8E06[0200]                  mov es,[curblk_ptr]       ; es -> block for curseg_ptr
   143 0000001B 268915                      mov [es:di],dx          ; save final overlaid public count for current segment
   144 0000001E 26896D02                    mov [es:di+2],bp        ; save far public references
   145 00000022 5F                          pop di                  ; di -> current overlaid public block from stack
   146 00000023 09D2                        or  dx,dx               ; see if any overlaid publics left for update length
   147 00000025 7519                        jne res_seg2            ; yes
   148 00000027 E9AC00                      jmp NEAR PTR res_blk_chk    ; no, bypass segment updates
   149                                  
   150                                  ; the segment is too long as a result of adding overlay overhead, fatal error
   151                                  res_seglen_err:
   152 0000002A 08C0                        or  al,al               ; see if overlay or root segment
   153 0000002C 7406                        je  res_rootseg_err     ; root
   154                                  
   155                                  res_ovlseg_err:
   156 0000002E B83C00                      mov ax,OVLSEG_LEN_ERR   ; overlay segment too long
   157 00000031 E9(0000)                    jmp NEAR PTR link_error ; transfer control to error handler
   158                                  
   159                                  res_rootseg_err:
   160 00000034 B83D00                      mov ax,ROOTSEG_LEN_ERR  ; root segment too long
   161 00000037 E9(0000)                    jmp NEAR PTR link_error ; transfer control to error handler
   162                                  
   163                                  res_ovlmodpub_err:
   164 0000003A B84200                      mov ax,OVL_MOD_PUB_MAX_ERR
   165 0000003D E9(0000)                    jmp NEAR PTR link_error ; transfer control to error handler
   166                                  
   167                                  res_seg2:
   168 00000040 8EC6                        mov es,si               ; es -> segment partition entry of completed overlaid public sequence
   169                                  
   170 00000042 81FAFF07                    cmp dx,OVL_MOD_PUB_MAX  ; see if too many overlaid public references
   171 00000046 77F2                        ja  res_ovlmodpub_err   ; yes
   172                                  
   173                                  ; adjust for far vector removal here
   174                                  ; subtract from dx the value at curblk_ptr:curseg_ptr+4 (far references)
   175 00000048 8CC0                        mov ax,es
   176 0000004A 8B36[0000]                  mov si,[curseg_ptr]
   177 0000004E 8E06[0200]                  mov es,[curblk_ptr]
   178 00000052 262B5404                    sub dx,[es:si+4]        ; back off far references count
   179 00000056 8EC0                        mov es,ax               ; restore es
   180                                  
   181 00000058 89D1                        mov cx,dx               ; save vector count in cx
   182                                  
   183 0000005A B80700                      mov ax,7
   184 0000005D F7E2                        mul dx                  ; get count of bytes required by vectors
   185 0000005F 89C2                        mov dx,ax               ; get value in dx
   186                                  
   187 00000061 26F6060F0080                test    BYTE PTR [es:15],80h    ; see if overlaid segment
   188 00000067 7548                        jne res_ovl_update      ; yes, update overlay segment
   189                                  
   190                                  ; update root segment
   191 00000069 268E060400                  mov es,[es:4]           ; get owner segdef entry
   192 0000006E 268B361E00                  mov si,[es:30]          ; get previous total vector bytes
   193 00000073 2601161E00                  add [es:30],dx          ; update total vector bytes count
   194 00000078 26F6061C0002                test    BYTE PTR [es:28],2  ; see if length update bit was previously set
   195 0000007E 7509                        jne res_old_update      ; yes
   196                                  
   197                                  ; first update for root segment, add 20h bytes for near and shared vector bytes
   198 00000080 26800E1C0002                or  BYTE PTR [es:28],2  ; set length updated bit
   199 00000086 83C220                      add dx,20h              ; bump dx value to be added to segment length
   200                                  
   201                                  res_old_update:
   202 00000089 2601160600                  add [es:6],dx           ; add vector bytes to segment length
   203 0000008E 730E                        jnc res_prev_vectbyte   ; segment length hasn't overflowed, continue
   204 00000090 26A10600                    mov ax,[es:6]           ; get new length
   205 00000094 09C0                        or  ax,ax               ; see if zero (segment okay if and only if new length is 64K)
   206 00000096 759C                        jne res_rootseg_err     ; segment too big
   207 00000098 26800E1A0002                or  BYTE PTR [es:26],2  ; set Big bit
   208                                  
   209                                  ; save the previous total vector byte count prior to this segment partition update
   210                                  res_prev_vectbyte:
   211 0000009E 89F0                        mov ax,si               ; get vector byte count prior to current vector bytes
   212 000000A0 8E06[0200]                  mov es,[curblk_ptr]       ; es -> block for curseg_ptr
   213 000000A4 8B36[0000]                  mov si,[curseg_ptr]       ; get pointer to current segment value
   214 000000A8 26894406                    mov [es:si+6],ax        ; save vector byte count to this segment partition entries vector bytes
   215                                  
   216 000000AC EB28                        jmp SHORT res_blk_chk   ; bypass overlay segment update
   217                                  
   218                                  ; jump to fatal error routine
   219                                  to_res_ovlseg_err:
   220 000000AE E97DFF                      jmp NEAR PTR res_ovlseg_err
   221                                  
   222                                  res_ovl_update:
   223 000000B1 83C220                      add dx,20h              ; bump dx value to be added to segment length for near/shared vectors
   224 000000B4 80CD10                      or  ch,10h              ; set overlaid segment length update bit
   225 000000B7 26880E0E00                  mov [es:14],cl          ; save low word of vector count
   226 000000BC 26082E0F00                  or  [es:15],ch          ; merge in high word of vector count with flag bits
   227                                  
   228 000000C1 2601160C00                  add [es:12],dx          ; add vector bytes to segment length
   229 000000C6 730E                        jnc res_blk_chk         ; segment length hasn't overflowed, continue
   230 000000C8 26A10C00                    mov ax,[es:12]          ; get new length
   231 000000CC 09C0                        or  ax,ax               ; see if zero (segment okay if and only if new length is 64K)
   232 000000CE 75DE                        jne to_res_ovlseg_err   ; segment too big
   233 000000D0 26800E0B0002                or  BYTE PTR [es:11],2  ; set Big bit
   234                                  
   235                                  ; check if in last block, if so, check if at last used position
   236                                  res_blk_chk:
   237 000000D6 8EC7                        mov es,di               ; restore es -> current overlaid public block
   238 000000D8 89F8                        mov ax,di
   239                                  
   240                                  res_blk_chk2:
   241 000000DA 3B06[0000]                  cmp ax,[alloc_ovlpubblk_ptr]  ; see if on last block
   242 000000DE 7515                        jne more_segs           ; no
   243 000000E0 3B1E[0000]                  cmp bx,[ovlpubblk_pos]    ; see if at last position
   244 000000E4 720F                        jb  more_segs           ; no
   245 000000E6 E96001                      jmp NEAR PTR chk_segdefs    ; yes, done
   246                                  
   247                                  ; internal error, this entry is not a segment partition entry
   248                                  res_internal_err:
   249 000000E9 B80000                      mov ax,INTERNAL_ERR     ; put warplink error code in ax
   250 000000EC B90B00                      mov cx,11               ; internal error value
   251 000000EF E9(0000)                    jmp NEAR PTR link_error ; transfer control to error handler
   252                                  
   253                                  to_res_count_err:
   254 000000F2 E91A01                      jmp NEAR PTR res_count_err
   255                                  
   256                                  ; check if room in block for reading in next segment partition info
   257                                  more_segs:
   258 000000F5 81FBF703                    cmp bx,OVLPUB_BLK_BYSIZE-9  ; see if at end of block, no room for segment partition entry info
   259 000000F9 7208                        jb  res_get_seg         ; no
   260 000000FB 268E060000                  mov es,[es:0]           ; get pointer to next block in ax
   261 00000100 BB0200                      mov bx,2                ; init block position
   262                                  
   263                                  res_get_seg:
   264 00000103 268A07                      mov al,[es:bx]          ; get flag byte
   265 00000106 3C02                        cmp al,2                ; check if equals non-overlay class segment partition value
   266 00000108 7406                        je  res_nonovl          ; yes
   267 0000010A 3C01                        cmp al,1                ; check if equals overlay class segment partition value
   268 0000010C 75DB                        jne res_internal_err    ; no, internal error
   269 0000010E EB7E                        jmp NEAR PTR res_seg_okay  ; yes
   270                                  
   271                                  ; Non-overlay class segment partition entry that references potentially
   272                                  ; overlaid publics.
   273                                  ; All that is necessary is to update the ovl_pubcount variable and
   274                                  ; the overlaid public number for the public declaration entry if overlaid.
   275                                  
   276                                  res_nonovl:
   277 00000110 43                          inc bx
   278 00000111 891E[0000]                  mov [curseg_ptr],bx       ; get position in block holding entry segment
   279 00000115 8C06[0200]                  mov [curblk_ptr],es       ; save block holding position
   280 00000119 268B4F04                    mov cx,[es:bx+4]        ; get far references (should only be far due to pointer filter)
   281 0000011D 31D2                        xor dx,dx               ; init overlaid public count after check for overlay class
   282 0000011F 31ED                        xor bp,bp               ; init far reference count too
   283 00000121 83C308                      add bx,8                ; scan past info to first overlaid public
   284 00000124 8B3E[0000]                  mov di,[ovl_pubcount]     ; get count of overlaid publics
   285                                  
   286                                  nonovl_loop:
   287 00000128 81FBFD03                    cmp bx,OVLPUB_BLK_BYSIZE-3  ; see if at end of block, no room for public declaration entry info
   288 0000012C 7208                        jb  nonovl_1            ; no
   289 0000012E 268E060000                  mov es,[es:0]           ; get pointer to next block in ax
   290 00000133 BB0200                      mov bx,2                ; init block position
   291                                  
   292                                  nonovl_1:
   293 00000136 268B4701                    mov ax,[es:bx+1]        ; get overlaid public declaration entry
   294 0000013A 1E                          push    ds              ; save data segment
   295 0000013B 8ED8                        mov ds,ax               ; ds -> public declaration entry
   296 0000013D 30C0                        xor al,al               ; setup al to reset far flag
   297 0000013F F6060F0001                  test    BYTE PTR [15],1  ; see if overlaid public
   298 00000144 7424                        je  nonovl_2            ; no
   299                                  
   300                                  ; overlaid public far referenced by non-overlay class segment
   301 00000146 A10200                      mov ax,[2]           ; get overlaid public number
   302 00000149 09C0                        or  ax,ax               ; see if overlaid public number is zero
   303 0000014B 740E                        je  newovl              ; zero, new overlaid public
   304                                  
   305                                  ; see if group flag is set, if so then number is a group pointer, reset and use
   306 0000014D 30C0                        xor al,al               ; setup al to reset far flag
   307 0000014F F6060F0080                  test    BYTE PTR [15],80h    ; check group bit
   308 00000154 7414                        je  nonovl_2            ; not in group, nonzero overlaid public number, already used
   309 00000156 80260F007F                  and BYTE PTR [15],7fh    ; reset group flag, use this overlaid public
   310                                  
   311                                  newovl:
   312 0000015B 47                          inc di                  ; bump overlaid public count
   313 0000015C 42                          inc dx                  ; bump count of overlaid publics for this segment partition
   314 0000015D 45                          inc bp                  ; bump count of far publics
   315 0000015E 81FFFF0F                    cmp di,OVERLAY_MAX_COUNT    ; check if maximum number of overlaid publics exceeded
   316 00000162 778E                        ja  to_res_count_err    ; yes, terminate with error
   317 00000164 893E0200                    mov [2],di           ; set overlaid public number for entry
   318 00000168 B080                        mov al,80h              ; setup al to set far flag
   319                                  
   320                                  nonovl_2:
   321 0000016A 268807                      mov [es:bx],al          ; re/set far flag
   322 0000016D 1F                          pop ds                  ; restore ds -> warplink data
   323 0000016E 83C303                      add bx,3                ; move to next overlaid public entry
   324 00000171 E2B5                        loop    nonovl_loop     ; loop through all entries
   325 00000173 893E[0000]                  mov [ovl_pubcount],di     ; update overlaid public count
   326                                  
   327 00000177 8CC0                        mov ax,es
   328 00000179 8B3E[0000]                  mov di,[curseg_ptr]       ; get pointer to old block segment value
   329 0000017D 8E06[0200]                  mov es,[curblk_ptr]       ; es -> block for curseg_ptr
   330 00000181 26895502                    mov [es:di+2],dx        ; save total overlaid public references for segment entry
   331 00000185 26896D04                    mov [es:di+4],bp        ; save far public references
   332                                  
   333 00000189 8EC0                        mov es,ax               ; restore es -> current overlaid public block
   334 0000018B E94CFF                      jmp NEAR PTR res_blk_chk2   ; get next segment partition entry in overlaid block
   335                                  
   336                                  res_seg_okay:
   337 0000018E 43                          inc bx
   338 0000018F 891E[0000]                  mov [curseg_ptr],bx       ; get position in block holding entry segment
   339 00000193 8C06[0200]                  mov [curblk_ptr],es       ; save block holding position
   340 00000197 268B37                      mov si,[es:bx]          ; get segment partition entry segment in si
   341 0000019A 268B4F02                    mov cx,[es:bx+2]        ; get near references in cx
   342 0000019E 26034F04                    add cx,[es:bx+4]        ; add in far references
   343 000001A2 31D2                        xor dx,dx               ; init overlaid public count after check for overlay class
   344 000001A4 31ED                        xor bp,bp               ; init far reference count too
   345 000001A6 83C308                      add bx,8                ; scan past info to first overlaid public
   346                                  
   347                                  res_get_pubs:
   348 000001A9 81FBFD03                    cmp bx,OVLPUB_BLK_BYSIZE-3  ; see if at end of block, no room for public declaration entry info
   349 000001AD 7208                        jb  resolve_1           ; no
   350 000001AF 268E060000                  mov es,[es:0]           ; get pointer to next block in ax
   351 000001B4 BB0200                      mov bx,2                ; init block position
   352                                  
   353                                  resolve_1:
   354 000001B7 268B4701                    mov ax,[es:bx+1]        ; get overlaid public declaration entry
   355 000001BB 8B3E[0000]                  mov di,[ovl_pubcount]
   356 000001BF 1E                          push    ds              ; save data segment
   357 000001C0 8ED8                        mov ds,ax               ; ds -> public declaration entry
   358                                  
   359 000001C2 F6060F0001                  test BYTE PTR [15],1 ; see if overlaid public
   360 000001C7 7419                        je  resolve_2           ; no, check overlay class bit
   361                                  
   362                                  ; overlaid public, see if owning segment partition matches current segment partition
   363 000001C9 3B360000                    cmp si,[0]           ; see if segment partition entries match
   364 000001CD 7527                        jne res_chk_pubnum      ; no, check public number to see if should update
   365                                  
   366                                  ; owning segment partition matches current segment partition
   367                                  ; ignore near calls
   368                                  ; only setup vectors for far calls internal to a routine
   369 000001CF 268A07                      mov al,[es:bx]          ; get flag bits
   370                                  
   371 000001D2 A840                        test al,40h             ; see if near bit set
   372 000001D4 7406                        je  res_chkfar          ; no, check far bit flag
   373 000001D6 24BF                        and al,0bfh             ; reset near bit
   374 000001D8 268807                      mov [es:bx],al          ; save new status of bit flags
   375 000001DB 49                          dec cx                  ; drop count of overlaid publics left to check
   376                                  
   377                                  res_chkfar:
   378 000001DC 2480                        and al,80h              ; get far bit flag
   379 000001DE 7448                        je  resolve_nextpub     ; not set, try next public
   380 000001E0 EB14                        jmp SHORT res_chk_pubnum    ; set, check public number to see if should update
   381                                  
   382                                  resolve_2:
   383 000001E2 F6060F0008                  test    BYTE PTR [15],8  ; check if overlay class bit
   384 000001E7 743F                        je  resolve_nextpub     ; not set, try next public
   385 000001E9 8CD8                        mov ax,ds               ; save ds -> overlaid public entry
   386 000001EB 8EDE                        mov ds,si               ; ds -> current segment partition entry from overlay publics block
   387 000001ED F6060F0080                  test    BYTE PTR [15],80h    ; see if segment partition is overlaid
   388 000001F2 8ED8                        mov ds,ax               ; restore ds -> overlaid public entry
   389 000001F4 7432                        je  resolve_nextpub     ; segment partition is not overlaid
   390                                  
   391                                  ; this public declaration meets the requirements for vectoring,
   392                                  ; in an different overlay from where it is called or in root called from an overlay
   393                                  ; now see if it has already had a public number assigned to it
   394                                  res_chk_pubnum:
   395 000001F6 A10200                      mov ax,[2]           ; get overlaid public number
   396 000001F9 09C0                        or  ax,ax               ; see if overlaid public number is zero
   397 000001FB 7518                        jne resolve_oldpub      ; no, already used
   398                                  
   399                                  res_bumpcount:
   400 000001FD 47                          inc di                  ; bump overlaid publics count
   401 000001FE 81FFFF0F                    cmp di,OVERLAY_MAX_COUNT    ; check if maximum number of overlaid publics exceeded
   402 00000202 770B                        ja  res_count_err       ; yes, terminate with error
   403                                  
   404                                  resolve_3:
   405 00000204 893E0200                    mov [2],di           ; save overlaid public number
   406 00000208 1F                          pop ds                  ; restore data segment
   407 00000209 893E[0000]                  mov [ovl_pubcount],di     ; update overlaid public count
   408 0000020D EB07                        jmp SHORT res_bump_count    ; bypass old public stack adjustment
   409                                  
   410                                  ; too many references to overlay class symbols
   411                                  res_count_err:
   412 0000020F B84000                      mov ax,OVLPUB_COUNT_ERR
   413 00000212 E9(0000)                    jmp NEAR PTR link_error ; transfer control to error handler
   414                                  
   415                                  resolve_oldpub:
   416 00000215 1F                          pop ds                  ; restore data segment
   417                                  
   418                                  ; bump the count of overlaid publics in dx, near and far are treated as discrete
   419                                  res_bump_count:
   420 00000216 268A07                      mov al,[es:bx]          ; get flag bits
   421 00000219 A880                        test    al,80h          ; see if far bit set
   422 0000021B 7403                        je  resolve_4           ; no
   423 0000021D 42                          inc dx
   424 0000021E 45                          inc bp                  ; bump count of far references
   425 0000021F 49                          dec cx
   426                                  
   427                                  resolve_4:
   428 00000220 2440                        and al,040h             ; see if near bit set
   429 00000222 7418                        je  res_update_pos      ; no
   430 00000224 42                          inc dx
   431 00000225 49                          dec cx
   432 00000226 EB14                        jmp SHORT res_update_pos    ; check next entry
   433                                  
   434                                  ; unvectored overlaid public
   435                                  resolve_nextpub:
   436 00000228 1F                          pop ds                  ; restore data segment
   437                                  
   438                                  ; decrement the value in cx for each near and far bit set
   439                                  resolve_next2:
   440 00000229 268A07                      mov al,[es:bx]
   441 0000022C 26C60700                    mov BYTE PTR [es:bx],0  ; zero out flag bits in entry (no vectors needed)
   442 00000230 24C0                        and al,0c0h             ; get near and far flag bits
   443 00000232 A880                        test    al,80h          ; see if far bit set
   444 00000234 7401                        je  res_next3           ; no
   445 00000236 49                          dec cx
   446                                  
   447                                  res_next3:
   448 00000237 2440                        and al,40h              ; see if near bit set
   449 00000239 7401                        je  res_update_pos      ; no
   450 0000023B 49                          dec cx
   451                                  
   452                                  res_update_pos:
   453 0000023C 83C303                      add bx,3                ; move to next overlaid public entry
   454 0000023F 09C9                        or  cx,cx               ; see if any overlaid publics left for this segment
   455 00000241 7403                        je  to_res_seg_done     ; no
   456 00000243 E963FF                      jmp NEAR PTR res_get_pubs   ; yes, loop back for them
   457                                  
   458                                  to_res_seg_done:
   459 00000246 E9C6FD                      jmp NEAR PTR res_seg_done   ;  move to next segment
   460                                  
   461                                  ; step thru each segdef entry
   462                                  ; if overlay class and length updated bit not set and length > 0
   463                                  ; then add 20h to length
   464                                  chk_segdefs:
   465 00000249 A1[0000]                    mov ax,[first_segdefblk_ptr]  ; get first segdef block pointer
   466                                  
   467                                  segdef_blkloop:
   468 0000024C 09C0                        or  ax,ax               ; see if another block
   469 0000024E 7448                        je  create_publookup    ; no
   470 00000250 8EC0                        mov es,ax               ; es -> segdef block
   471 00000252 8CC6                        mov si,es               ; keep -> segdef block
   472                                  
   473 00000254 268B0E0000                  mov cx,[es:0]           ; get count of entries in block
   474 00000259 40                          inc ax                  ; bump to first segdef entry in block
   475                                  
   476                                  segdef_entloop:
   477 0000025A 8EC0                        mov es,ax               ; es -> segdef entry
   478 0000025C 26A01C00                    mov al,[es:28]          ; get overlay flag
   479 00000260 2403                        and al,3                ; get overlay class and length updated bits
   480 00000262 7425                        je  next_segdef         ; not overlay class
   481 00000264 2402                        and al,2                ; get length updated bit
   482 00000266 7521                        jne next_segdef         ; length updated
   483                                  
   484                                  ; overlay class and length not updated
   485 00000268 26833E060000                cmp WORD PTR [es:6],0   ; see if length of segment was 0 (no calls to segment)
   486 0000026E 7419                        je  next_segdef         ; yes
   487 00000270 268306060020                add WORD PTR [es:6],20h ; add space for near vector (must include space for shared vector too)
   488 00000276 7311                        jnc next_segdef         ; no overflow
   489 00000278 26A10600                    mov ax,[es:6]
   490 0000027C 09C0                        or  ax,ax               ; see if zero after overflow (segment now 64K)
   491 0000027E 7403                        je  seg_len_okay        ; yes
   492 00000280 E9B1FD                      jmp NEAR PTR res_rootseg_err    ; no, segment length overflow
   493                                  
   494                                  seg_len_okay:
   495 00000283 26800E1C0002                or  BYTE PTR [es:28],2  ; set Big bit
   496                                  
   497                                  next_segdef:
   498 00000289 8CC0                        mov ax,es               ; get old segdef entry
   499 0000028B 83C002                      add ax,2                ; move to next segdef entry in block
   500 0000028E E2CA                        loop    segdef_entloop  ; loop through all entries in block
   501                                  
   502 00000290 8EC6                        mov es,si               ; restore es -> segdef block
   503 00000292 26A10200                    mov ax,[es:2]           ; get pointer to next block, if any
   504 00000296 EBB4                        jmp SHORT segdef_blkloop    ; loop for next block
   505                                  
   506                                  ; update length of the public lookup segment
   507                                  ; allocation equals ovl_pubcount*4 bytes
   508                                  create_publookup:
   509 00000298 A1[0000]                    mov ax,[lookup_tbl_segdef]    ; get segdef entry for overlaid public lookup table
   510 0000029B 8EC0                        mov es,ax               ; es -> segdef entry for segment
   511 0000029D A1[0000]                    mov ax,[ovl_pubcount]     ; get count of overlaid publics
   512 000002A0 D1E0                        shl ax,1
   513 000002A2 D1E0                        shl ax,1
   514 000002A4 D1E0                        shl ax,1                ; quadword entry for each public
   515 000002A6 26A30600                    mov [es:6],ax           ; save segment length
   516                                  
   517                                  ; update length of the indirect call segment
   518                                  ; allocate equals ovl_pubcount*3 + 16 bytes
   519 000002AA A1[0000]                    mov ax,[ind_tbl_segdef]   ; get segdef entry for overlaid public indirect call table
   520 000002AD 8EC0                        mov es,ax               ; es -> segdef entry for segment
   521 000002AF A1[0000]                    mov ax,[ovl_pubcount]     ; get count of overlaid publics
   522 000002B2 89C3                        mov bx,ax
   523 000002B4 D1E0                        shl ax,1                ; x2
   524 000002B6 01D8                        add ax,bx               ; x3
   525 000002B8 83C010                      add ax,10h              ; x3+10h
   526 000002BB 26A30600                    mov [es:6],ax           ; save segment length
   527                                  
   528                                  ; update length of the segment call via segment fixup segment
   529                                  ; allocate equals ovl_count*3 + 16 bytes
   530 000002BF A1[0000]                    mov ax,[segcall_tbl_segdef]   ; get segdef entry for overlaid public indirect call table
   531 000002C2 8EC0                        mov es,ax               ; es -> segdef entry for segment
   532 000002C4 A1[0000]                    mov ax,[ovl_count]        ; get count of overlays
   533 000002C7 89C3                        mov bx,ax
   534 000002C9 D1E0                        shl ax,1                ; x2
   535 000002CB 01D8                        add ax,bx               ; x3
   536 000002CD 83C010                      add ax,10h              ; x3+10h
   537 000002D0 26A30600                    mov [es:6],ax           ; save segment length
   538                                  
   539                                  ; create and write system info to OVL file, pad remaining with zeros
   540                                  write_ovl_sysinfo:
   541 000002D4 E8(0000)                    call    setup_ovl_file  ; create the overlay file and write information to it
   542                                  
   543                                  ; feedback minimum overlay allocation, and adjust max/give warning if necessary
   544 000002D7 E80100                      call    get_min_ovl_alloc
   545                                  
   546 000002DA C3                          ret
   547                                  resolve_ovl_info    ENDP
   548                                  
   549                                  ;*****************************
   550                                  ;* GET_MIN_OVL_ALLOC         *
   551                                  ;*****************************
   552                                  
   553                                  ; check that minimum overlay allocation does exceed maximum, adjust if so and
   554                                  ; give associated warning
   555                                  ; feedback the minimum overlay allocation amount
   556                                  ; destroys ax,bx,cx,dx,di
   557                                  
   558                                  get_min_ovl_alloc   PROC
   559 000002DB A1[0000]                    mov ax,[largest_ovl]      ; get size of largest overlay in bytes
   560 000002DE 05FF03                      add ax,1023             ; round up to next 1K boundary
   561 000002E1 7308                        jnc gm_2                ; no overflow
   562 000002E3 B84000                      mov ax,64               ; segment page size is 64K
   563 000002E6 BB0001                      mov bx,256              ; bx holds page size in 256 byte blocks
   564 000002E9 EB0D                        jmp SHORT gm_3          ; bypass segment page size calculation
   565                                  
   566                                  gm_2:
   567 000002EB 2500FC                      and ax,0fc00h           ; put on 1K boundary
   568 000002EE 88E0                        mov al,ah
   569 000002F0 30E4                        xor ah,ah               ; effective divide by 256
   570 000002F2 89C3                        mov bx,ax               ; save page size in 256 byte blocks
   571 000002F4 D1E8                        shr ax,1                ; /512
   572 000002F6 D1E8                        shr ax,1                ; /1024, ax holds 1K pages of overlay
   573                                  
   574                                  gm_3:
   575 000002F8 803E[0000]00                cmp byte [is_min_pool],0       ; see if minimum pool size specified
   576 000002FD 7404                        je  gm_3a               ; no
   577 000002FF 891E[0100]                  mov WORD PTR [ovl_pool+1],bx  ; set the pool size to required minimum
   578                                  
   579                                  gm_3a:
   580 00000303 803E[0000]00                cmp byte [ovl_mem_alloc],0     ; see if pool size if free memory or memory to allocate
   581 00000308 7429                        je  gm_minfeed          ; free memory
   582                                  
   583                                  ; check that largest overlay doesn't exceed specified pool size
   584 0000030A 833E[0200]00                cmp WORD [ovl_pool+2],0   ; see if overlay pool MSW is nonzero (pool >=64K)
   585 0000030F 7522                        jne gm_minfeed          ; yes, overlay pool size is okay
   586 00000311 3B1E[0100]                  cmp bx,WORD PTR [ovl_pool+1]  ; see largest overlay if exceeds overlay pool
   587 00000315 761C                        jbe gm_minfeed          ; no
   588                                  
   589                                  ; ajust the maximum overlay pool size, give warning feedback
   590 00000317 891E[0100]                  mov WORD PTR [ovl_pool+1],bx
   591 0000031B BB[0100]                    mov bx,OFFSET max_text wrt DGROUP
   592 0000031E 89C7                        mov di,ax               ; save minimum allocation
   593 00000320 8A4FFF                      mov cl,[bx-1]           ; get length of string to print
   594 00000323 89DA                        mov dx,bx               ; ds:dx -> string
   595 00000325 30ED                        xor ch,ch               ; zap high byte of cx
   596 00000327 BB0100                      mov bx,STDOUT           ; write to standard output device
   597 0000032A B440                        mov ah,40h              ; write to device
   598 0000032C CD21                        int 21h
   599 0000032E E8(0000)                    call    restore_ems_map
   600 00000331 89F8                        mov ax,di               ; restore minimum allocation to ax
   601                                  
   602                                  ; give minimum overlay allocation feedback, K amount in ax
   603                                  gm_minfeed:
   604 00000333 BB[4800]                    mov bx,OFFSET min_text wrt DGROUP
   605 00000336 E88D00                      call    give_min_feedback
   606                                  
   607                                  ; print largest overlay code segment name in parens after allocation
   608 00000339 B90100                      mov cx,1
   609 0000033C BA[0500]                    mov dx,OFFSET left_paren wrt DGROUP ; print left parenthesis
   610 0000033F B440                        mov ah,40h
   611 00000341 CD21                        int 21h
   612 00000343 E8(0000)                    call    restore_ems_map
   613                                  
   614 00000346 C51E[0000]                  lds bx,[large_ovl_name]   ; ds:bx -> largest overlay code segment name
   615 0000034A 89DA                        mov dx,bx               ; save pointer to beginning of string
   616 0000034C 31C9                        xor cx,cx               ; init count of chars in string
   617                                  
   618                                  name_loop:
   619 0000034E 8A07                        mov al,[bx]             ; get char
   620 00000350 08C0                        or  al,al               ; see if at end
   621 00000352 7404                        je  print_name          ; yes
   622 00000354 41                          inc cx                  ; bump count of chars in name
   623 00000355 43                          inc bx                  ; bump to next char
   624 00000356 EBF6                        jmp SHORT name_loop
   625                                  
   626                                  print_name:
   627 00000358 BB0100                      mov bx,STDOUT           ; write to standard output device
   628 0000035B B440                        mov ah,40h              ; write to device
   629 0000035D CD21                        int 21h
   630 0000035F E8(0000)                    call    restore_ems_map
   631                                  
   632 00000362 B8[ssss]                    mov ax,DGROUP           ; restore ds -> warplink data
   633 00000365 8ED8                        mov ds,ax
   634                                  
   635 00000367 B90300                      mov cx,3
   636 0000036A BA[0600]                    mov dx,OFFSET right_paren wrt DGROUP    ; print right parenthesis and cr/lf
   637 0000036D B440                        mov ah,40h              ; write to device
   638 0000036F CD21                        int 21h
   639 00000371 E8(0000)                    call    restore_ems_map
   640                                  
   641 00000374 A0[0000]                    mov al,[is_reload]
   642 00000377 0A06[0000]                  or  al,[is_clarion]       ; see if reload flag or Clarion flag tripped
   643 0000037B 7448                        je  gm_ret              ; no
   644                                  
   645                                  ; give required overlay allocation (2 x largest - 1 + 2nd largest)
   646 0000037D BB[6F00]                    mov bx,OFFSET rec_text wrt DGROUP
   647                                  
   648 00000380 803E[0000]00                cmp byte [is_clarion],0        ; see if Clarion switch thrown
   649 00000385 7403                        je  gm_4                ; no
   650 00000387 BB[8F00]                    mov bx,OFFSET clar_text wrt DGROUP  ; use clarion-specific feedback
   651                                  
   652                                  gm_4:
   653 0000038A 89F8                        mov ax,di               ; get largest overlay size
   654 0000038C D1E0                        shl ax,1                ; x2
   655 0000038E 48                          dec ax                  ; x2-1
   656 0000038F 89C1                        mov cx,ax
   657 00000391 A1[0000]                    mov ax,[second_ovl]       ; add in second largest in paragraphs
   658 00000394 05FF03                      add ax,1023             ; round up to next 1K boundary
   659 00000397 2500FC                      and ax,0fc00h           ; put on 1K boundary
   660 0000039A 88E0                        mov al,ah
   661 0000039C 30E4                        xor ah,ah               ; effective divide by 256
   662 0000039E D1E8                        shr ax,1                ; /512
   663 000003A0 D1E8                        shr ax,1                ; /1024, ax holds 1K pages of overlay
   664 000003A2 01C8                        add ax,cx               ; x2-1 + 2nd
   665 000003A4 803E[0000]00                cmp byte [is_min_pool],0       ; see if automatically use minimum pool size
   666 000003A9 740A                        je  gm_5                ; no
   667                                  
   668 000003AB 89C1                        mov cx,ax               ; get pool size in 1K blocks
   669 000003AD D1E1                        shl cx,1
   670 000003AF D1E1                        shl cx,1                ; pool size in 256 byte pages
   671 000003B1 890E[0100]                  mov WORD PTR [ovl_pool+1],cx  ; set the pool size to required minimum
   672                                  
   673                                  gm_5:
   674 000003B5 E80E00                      call    give_min_feedback
   675                                  
   676                                  ; print trailing CR/LF
   677 000003B8 BA[4800]                    mov dx,OFFSET min_text wrt DGROUP
   678 000003BB B90200                      mov cx,2
   679 000003BE B440                        mov ah,40h              ; write to device
   680 000003C0 CD21                        int 21h
   681 000003C2 E8(0000)                    call    restore_ems_map
   682                                  
   683                                  gm_ret:
   684 000003C5 C3                          ret
   685                                  get_min_ovl_alloc   ENDP
   686                                  
   687                                  ;*****************************
   688                                  ;* GIVE_MIN_FEEDBACK         *
   689                                  ;*****************************
   690                                   
   691                                  ; give minimum overlay allocation feedback
   692                                  ; upon entry bx -> text string to print, ax holds value
   693                                  ; return initial ax value in di, STDOUT in bx
   694                                  ; destroys ax,bx,cx,dx,di
   695                                  
   696                                  give_min_feedback   PROC
   697 000003C6 89C7                        mov di,ax               ; save minimum allocation
   698 000003C8 8A4FFF                      mov cl,[bx-1]           ; get length of string to print
   699 000003CB 89DA                        mov dx,bx               ; ds:dx -> string
   700 000003CD 30ED                        xor ch,ch               ; zap high byte of cx
   701 000003CF BB0100                      mov bx,STDOUT           ; write to standard output device
   702 000003D2 B440                        mov ah,40h              ; write to device
   703 000003D4 CD21                        int 21h
   704 000003D6 E8(0000)                    call    restore_ems_map
   705 000003D9 89F8                        mov ax,di               ; restore minimum allocation to ax
   706                                  
   707 000003DB BB[0000]                    mov bx,OFFSET tbuff wrt DGROUP  ; bx -> buffer to hold ax value
   708 000003DE 83F864                      cmp ax,100              ; see if minimum required >=100
   709 000003E1 7206                        jb  gmf_1               ; no
   710 000003E3 C60731                      mov BYTE PTR [bx],'1'
   711 000003E6 83E864                      sub ax,100
   712                                  
   713                                  gmf_1:
   714 000003E9 B10A                        mov cl,10
   715 000003EB F6F1                        div cl                  ; al holds decimal byte, ah holds ones
   716 000003ED 0D3030                      or  ax,3030h            ; convert to ASCII values
   717 000003F0 3C30                        cmp al,30h              ; see if leading zero
   718 000003F2 7502                        jne gmf_2               ; no
   719 000003F4 B020                        mov al,' '              ; use blank instead
   720                                  
   721                                  gmf_2:
   722 000003F6 894701                      mov [bx+1],ax           ; store value in buffer
   723 000003F9 89DA                        mov dx,bx               ; ds:dx -> string to print
   724 000003FB B90500                      mov cx,5                ; # bytes to print
   725 000003FE BB0100                      mov bx,STDOUT           ; write to standard output device
   726 00000401 B440                        mov ah,40h              ; write to device
   727 00000403 CD21                        int 21h
   728 00000405 E8(0000)                    call    restore_ems_map
   729 00000408 C3                          ret
   730                                  give_min_feedback   ENDP
   731                                  
   732                                  ;*****************************
   733                                  ;* MAKE_MASTER_SEGBLK        *
   734                                  ;*****************************
   735                                  
   736                                  ; allocate a block to hold the master segdef entry pointers for each overlaid
   737                                  ; segment partition entry, as they are overwritten
   738                                  ; destroys ax,bx
   739                                  
   740                                  make_master_segblk  PROC
   741 00000409 8B1E[0000]                  mov bx,[ovl_count]        ; get count of overlays
   742 0000040D 83C307                      add bx,7                ; round up
   743 00000410 D1EB                        shr bx,1                ; 2 bytes per entry, convert to paragraphs for allocation
   744 00000412 D1EB                        shr bx,1                ; /4
   745 00000414 D1EB                        shr bx,1                ; /8, bx holds paragraphs to allocate
   746 00000416 E8(0000)                    call    alloc_memory    ; allocate block
   747 00000419 A3[0000]                    mov [master_segblk],ax    ; save address of block
   748 0000041C C3                          ret
   749                                  make_master_segblk  ENDP
   750                                  
   751                                  ;*****************************
   752                                  ;* OVL_ENTRY_POINT           *
   753                                  ;*****************************
   754                                  
   755                                  ; make new entry point that goes to overlay manager initialization code
   756                                  
   757                                  ovl_entry_point PROC
   758 0000041D BF[B300]                    mov di,OFFSET entry_text wrt DGROUP
   759 00000420 E8(0000)                    call    find_pubdecl_entry  ; find the symbol
   760 00000423 09C0                        or  ax,ax               ; make sure nonzero
   761 00000425 740B                        je  oep_mgrerr          ; not found, assume overlay manager wasn't linked in
   762                                  
   763 00000427 E8(0000)                    call    get_symbol_segoff
   764 0000042A A3[0000]                    mov [entry_offval],ax     ; save entry offset value
   765 0000042D 8916[0000]                  mov [entry_segval],dx     ; save entry segment value
   766 00000431 C3                          ret
   767                                  
   768                                  ; overlay manager not linked in, fatal error
   769                                  oep_mgrerr:
   770 00000432 B84100                      mov ax,MISSING_OVLMGR_ERR
   771 00000435 E9(0000)                    jmp NEAR PTR link_error
   772                                  
   773                                  ovl_entry_point ENDP
   774                                  
   775                                  ;*****************************
   776                                  ;* FIXUP_OVL_EXTDEF          *
   777                                  ;*****************************
   778                                  
   779                                  ; check if extdef in fixup should have offset changed to vector
   780                                  ; if so, change the offset
   781                                  ; upon entry es -> public declaration entry
   782                                  ; returns al nonzero if offset changed, zero if not and should continue with fixup process
   783                                  ; destroys ax,bx
   784                                  
   785                                  fixup_ovl_extdef    PROC
   786 00000438 51                          push    cx              ; save critical register
   787 00000439 52                          push    dx
   788 0000043A 57                          push    di
   789 0000043B 56                          push    si
   790 0000043C 06                          push    es
   791 0000043D 55                          push    bp
   792                                  
   793 0000043E 803E[0000]01                cmp byte [frame_method],1      ; see if group fixup
   794 00000443 7512                        jne foe_notgroup        ; no
   795 00000445 26F6060F0001                test    BYTE PTR [es:15],1  ; see if overlaid public
   796 0000044B 740A                        je  foe_notgroup        ; no
   797                                  
   798                                  ; group frame with overlaid extdef, set is_ind_call flag so that the
   799                                  ; group computation is bypassed and zero the target segment
   800 0000044D 31C0                        xor ax,ax
   801 0000044F A3[0000]                    mov [target_segment],ax   ; zero target segment
   802 00000452 FEC0                        inc al
   803 00000454 A2[0000]                    mov [is_ind_call],al      ; set indirect call flag so frame computation bypassed
   804                                  
   805                                  foe_notgroup:
   806 00000457 A0[0000]                    mov al,[loc]              ; get loc field
   807 0000045A 3C01                        cmp al,1                ; see if offset
   808 0000045C 7417                        je  foe_1               ; yes
   809 0000045E 3C05                        cmp al,5                ; see if alternate offset
   810 00000460 7413                        je  foe_1
   811 00000462 3C03                        cmp al,3                ; see if pointer (seg:off)
   812 00000464 740F                        je  foe_1               ; yes
   813 00000466 3C02                        cmp al,2                ; see if base fixup
   814 00000468 7508                        jne to_foe_retzero      ; no
   815                                  
   816                                  ; base fixup of overlay class public with current segment overlaid
   817                                  ; or base fixup of overlaid public
   818                                  
   819                                  ; remove use of far vectors within segment
   820 0000046A 30FF                        xor bh,bh               ; flag nonzero target disp warning if needed
   821 0000046C E8A401                      call    fixup_ind_ref_extdef
   822 0000046F E99401                      jmp NEAR PTR foe_retone
   823                                  
   824                                  to_foe_retzero:
   825 00000472 E99501                      jmp NEAR PTR foe_retzero    ; no, don't process other types of loc fields
   826                                  
   827                                  foe_1:
   828 00000475 8CC7                        mov di,es               ; save -> public declaration entry in di
   829                                  
   830                                  ; vector offset fixups if current segment
   831                                  ; matches target and far (matching base) and bracketed overlays, otherwise
   832                                  ; if current matches target, no vectoring
   833                                  
   834                                  foe_2:
   835                                  
   836                                  ; give warning on nonzero target displacement
   837 00000477 B001                        mov al,1
   838 00000479 A2[0000]                    mov [no_fixbyte_flag],al  ; set the flag to indicate fixup bytes at location should be zero
   839 0000047C A1[0000]                    mov ax,WORD PTR [target_disp]
   840 0000047F 0B06[0200]                  or  ax,WORD PTR [target_disp+2]
   841 00000483 7412                        je  foe_2a              ; zero target displacement
   842                                  
   843                                  ; nonzero target displacment, give warning
   844 00000485 06                          push    es              ; save critical registers
   845 00000486 57                          push    di
   846 00000487 26C43E0400                  les di,[es:4]           ; es:di -> symbol name
   847 0000048C BA[0000]                    mov dx,OFFSET filename wrt DGROUP   ; ds:dx -> filename with problem
   848 0000048F B84400                      mov ax,NONOVL_SYM_WARN  ; nonoverlayable symbol warning
   849 00000492 E8(0000)                    call    link_warning
   850 00000495 5F                          pop di                  ; restore critical registers
   851 00000496 07                          pop es
   852                                  
   853                                  foe_2a:
   854 00000497 8B1E[0000]                  mov bx,WORD PTR [ovl_pub_seg_ptr]
   855 0000049B A1[0200]                    mov ax,WORD PTR [ovl_pub_seg_ptr+2]
   856 0000049E 8EC0                        mov es,ax               ; es:bx -> total overlaid public references entry in overlaid public block
   857 000004A0 09D8                        or  ax,bx               ; see if zeroed (no table reference)
   858 000004A2 74CE                        je  to_foe_retzero      ; zero, no table entries, no vectoring necessary
   859                                  
   860                                  ; remember bx is offset by 2 from start of overlaid public entry
   861                                  foe_2b:
   862 000004A4 268B0F                      mov cx,[es:bx]          ; cx holds total overlaid public references
   863                                  
   864 000004A7 262B4F02                    sub cx,[es:bx+2]        ; subtract off far ref., cx holds NEAR public references
   865                                  
   866 000004AB 268B7704                    mov si,[es:bx+4]        ; get previous total vector bytes count (if non-overlaid segment)
   867 000004AF 31D2                        xor dx,dx               ; dx holds current count
   868 000004B1 31ED                        xor bp,bp               ; bp flags whether entry found as zero
   869 000004B3 83C306                      add bx,6                ; bump to first overlaid public byte
   870 000004B6 EB17                        jmp SHORT foe_boundchk  ; see if at end of block
   871                                  
   872                                  foe_seekloop:
   873 000004B8 268A07                      mov al,[es:bx]          ; get overlaid public flag byte
   874 000004BB A803                        test    al,3            ; see if segment info (overshot on this entry)
   875 000004BD 7536                        jne foe_new_entry       ; segment info, multiple segment entries
   876 000004BF 24C0                        and al,0c0h             ; get far and near bits
   877 000004C1 753E                        jne foe_4               ; nonzero
   878                                  
   879                                  ; check if entry matches zero'ed out entry, in case of bracketed intrasegment near offset
   880 000004C3 263B7F01                    cmp di,[es:bx+1]        ; see if public declaration entry segment matches current
   881 000004C7 7503                        jne foe_next            ; no
   882 000004C9 BD0100                      mov bp,1                ; yes, flag it
   883                                  
   884                                  foe_next:
   885 000004CC 83C303                      add bx,3                ; bump to next public entry
   886                                  
   887                                  foe_boundchk:
   888 000004CF 81FBFD03                    cmp bx,OVLPUB_BLK_BYSIZE-3  ; see if at end of block
   889 000004D3 72E3                        jb  foe_seekloop        ; no
   890                                  
   891                                  ; new block
   892 000004D5 26A10000                    mov ax,[es:0]           ; get pointer to next block in ax
   893 000004D9 09C0                        or  ax,ax               ; make sure non-null
   894 000004DB 7407                        je  foe_internal        ; null, internal error
   895 000004DD 8EC0                        mov es,ax               ; es -> next block
   896 000004DF BB0200                      mov bx,2                ; init block position
   897 000004E2 EBD4                        jmp SHORT foe_seekloop  ; try new block
   898                                  
   899                                  foe_internal:
   900 000004E4 09ED                        or  bp,bp               ; see if entry found as zero (not an error)
   901 000004E6 758A                        jne to_foe_retzero      ; yes, don't vector
   902                                  
   903 000004E8 B80000                      mov ax,INTERNAL_ERR     ; put WarpLink error code in ax
   904 000004EB B90E00                      mov cx,14               ; internal error value
   905                                  
   906                                  foe_toerr:
   907 000004EE 8B36[0000]                  mov si,[fixup_pos]        ; si -> offending fixupp record
   908 000004F2 E9(0000)                    jmp NEAR PTR link_error ; transfer control to error handler
   909                                  
   910                                  ; this may be recoverable in the future, but for now a fatal error
   911                                  foe_new_entry:
   912 000004F5 09ED                        or  bp,bp               ; see if entry found as zero (not an error)
   913 000004F7 7539                        jne to_foe_retzero2     ; yes, don't vector
   914                                  
   915                                  ; multiple segment entries, noncontiguous overlay class segment code, fatal error
   916                                  ; because the vectors will be screwed up
   917 000004F9 B84500                      mov ax,NONCONT_OVLDATA_ERR  ; put WarpLink error code in ax
   918 000004FC BA[0000]                    mov dx,OFFSET filename wrt DGROUP
   919 000004FF EBED                        jmp SHORT foe_toerr
   920                                  
   921                                  foe_4:
   922 00000501 263B7F01                    cmp di,[es:bx+1]        ; see if public declaration entry segment matches current
   923 00000505 7438                        je  foe_match           ; yes
   924                                  
   925                                  foe_5:
   926 00000507 2440                        and al,40h              ; see if near bit set
   927 00000509 74C1                        je  foe_next            ; no
   928 0000050B 42                          inc dx                  ; yes, bump current overlaid public count
   929 0000050C EBBE                        jmp SHORT foe_next      ; loop for next entry
   930                                  
   931                                  ; far reference, instead of vector within segment, make vector to indirect call table
   932                                  foe_far:
   933                                  
   934                                  ; vector pointer fixups if current segment matches target
   935                                  ; and bracketed overlays, if parens then no vectoring
   936 0000050E 803E[0000]03                cmp byte [loc],3               ; see if pointer fixup
   937 00000513 7520                        jne foe_farvect         ; no
   938 00000515 803E[0000]00                cmp byte [nonovl_rvect],0      ; see if nonvector root call flag is set
   939 0000051A 7419                        je  foe_farvect         ; no, vector code
   940                                  
   941 0000051C 268E060000                  mov es,[es:0]           ; es -> segment partition entry owning public
   942 00000521 833E[0000]00                cmp word [ovl_code_id],0       ; see if current segment is overlaid
   943 00000526 740D                        je  foe_farvect         ; no, must vector
   944 00000528 26A10400                    mov ax,[es:4]           ; get overlay identifier of owning segment
   945 0000052C 3B06[0000]                  cmp ax,[ovl_code_id]      ; see if matches current segment's
   946 00000530 7503                        jne foe_farvect         ; no, must vector
   947                                  
   948                                  ; current segment matches the target segment for this extdef
   949                                  ; and nonbracketed overlay, don't vector it
   950                                  to_foe_retzero2:
   951 00000532 E9D500                      jmp NEAR PTR foe_retzero    ; yes, no vectoring needed
   952                                  
   953                                  foe_farvect:
   954 00000535 8EC7                        mov es,di               ; restore es -> public declaration
   955 00000537 B701                        mov bh,1                ; flag no nonzero target disp warning (already given if needed)
   956 00000539 E8D700                      call    fixup_ind_ref_extdef
   957 0000053C E9C700                      jmp NEAR PTR foe_retone
   958                                  
   959                                  ; public declaration entry segment matches current public declaration in fixup
   960                                  foe_match:
   961                                  
   962                                  ; Check if al holds far reference, loc==3 (pointer).  If not, (loc==1 or 5, offset),
   963                                  ; then check if extdef segment if overlaid.  If not, walk the extdef's segdef
   964                                  ; segment partition list and see if matches the L?DATA segment partition entry.
   965                                  ; If not (not in same segment), assume not a near call, and don't vector.
   966 0000053F 8EC7                        mov es,di               ; restore es -> public declaration
   967 00000541 F606[0000]40                test    BYTE [locat],40h  ; see if M bit set
   968 00000546 7404                        je  foe_near            ; no, self-relative assume this is NEAR call, ignore far bit setting
   969 00000548 2480                        and al,80h              ; see if far bit set
   970 0000054A 75C2                        jne foe_far             ; yes
   971                                  
   972                                  ; near bit set, check if current segment is overlaid segment
   973                                  ; if so, then don't vector EVEN if bracketed
   974                                  foe_near:
   975 0000054C 268E060000                  mov es,[es:0]           ; es -> segment partition entry owning public
   976 00000551 833E[0000]00                cmp word [ovl_code_id],0       ; see if current segment is overlaid
   977 00000556 740A                        je  foe_nearvchk        ; no, continue vector check
   978 00000558 26A10400                    mov ax,[es:4]           ; get overlay identifier of owning segment
   979 0000055C 3B06[0000]                  cmp ax,[ovl_code_id]      ; see if matches current segment's
   980 00000560 74D0                        je  to_foe_retzero2     ; yes, no vectoring required
   981                                  
   982                                  ; should never be a pointer with near bit set, but this makes sure
   983                                  foe_nearvchk:
   984 00000562 803E[0000]03                cmp byte [loc],3               ; see if pointer
   985 00000567 7437                        je  foe_6               ; yes
   986                                  
   987 00000569 8EC7                        mov es,di               ; es -> public declaration entry
   988 0000056B 26F6060F0001                test    BYTE PTR [es:15],1  ; see if overlaid public
   989 00000571 752D                        jne foe_6               ; yes
   990 00000573 268E060000                  mov es,[es:0]           ; es -> segment partition entry
   991 00000578 268E060400                  mov es,[es:4]           ; es -> master segdef entry
   992 0000057D A1[0000]                    mov ax,[data_seg_part]    ; ax holds L?DATA segment partition entry to match
   993 00000580 268E061600                  mov es,[es:22]          ; es -> first segment partition entry
   994 00000585 800E[0000]01                or  byte [gen_flags],1         ; initially set bitflag for no vector address change
   995                                  
   996                                  foe_nearloop:
   997 0000058A 8CC3                        mov bx,es
   998 0000058C 09DB                        or  bx,bx               ; see if any more entries to match
   999 0000058E 747A                        je  foe_retzero         ; no, not found, assume NOT a near call to be vectored
  1000 00000590 39D8                        cmp ax,bx               ; see if found a match for segment partition entry
  1001 00000592 7407                        je  foe_5a              ; yes, assume a near call, continue with vectoring
  1002 00000594 268E060200                  mov es,[es:2]           ; es -> next segment partition entry, if any
  1003 00000599 EBEF                        jmp SHORT foe_nearloop  ; keep looking
  1004                                  
  1005                                  foe_5a:
  1006 0000059B 8026[0000]FE                and byte [gen_flags],0feh      ; reset no vector address change in frame bitflag
  1007                                  
  1008                                  foe_6:
  1009 000005A0 8E06[0000]                  mov es,[data_seg_part]    ; es -> L?DATA segment partition entry
  1010 000005A4 26F6060F0080                test    BYTE PTR [es:15],80h    ; see if segment is overlaid
  1011 000005AA 741A                        je  foe_7               ; no
  1012 000005AC 29D1                        sub cx,dx               ; get overlaid public adjustment to make to length
  1013 000005AE B80700                      mov ax,7
  1014 000005B1 F7E1                        mul cx                  ; compute proper adjustment for vector in ax
  1015 000005B3 268B1E0C00                  mov bx,[es:12]          ; get segment length in bx
  1016 000005B8 29C3                        sub bx,ax               ; bx holds offset to proper vector
  1017                                  
  1018                                  foe_update:
  1019 000005BA 891E[0000]                  mov WORD PTR [target_prog_off],bx ; update target_prog_off variable with offset
  1020 000005BE C706[0200]0000              mov WORD [target_prog_off+2],0    ; zero high word of offset
  1021 000005C4 EB40                        jmp SHORT foe_retone    ; bypass nonoverlaid segment code
  1022                                  
  1023                                  ; root segment calling overlay vector.
  1024                                  ; SEGMENT RELATIVE (M bit set):
  1025                                  ; get segment offset of symbol in target_prog_off
  1026                                  ; SELF RELATIVE (M bit reset):
  1027                                  ; add data_offset to segment offset of symbol to get its absolute address,
  1028                                  ; BUT data_offset also has partition offset, so subtract that off
  1029                                  foe_7:
  1030 000005C6 268B0E0000                  mov cx,[es:0]           ; get partition offset value, for self relative fixup
  1031 000005CB 268E060400                  mov es,[es:4]           ; es -> master segdef entry
  1032 000005D0 268B1E0600                  mov bx,[es:6]           ; bx holds segment length
  1033 000005D5 262B1E1E00                  sub bx,[es:30]          ; subtract off all end vector bytes
  1034 000005DA 01F3                        add bx,si               ; adjust past previous vector bytes
  1035 000005DC B80700                      mov ax,7
  1036 000005DF F7E2                        mul dx                  ; compute proper adjustment for vector in ax
  1037 000005E1 01C3                        add bx,ax               ; bx holds offset to proper vector within segment
  1038                                  
  1039 000005E3 F606[0000]40                test    BYTE [locat],40h  ; see if M bit set
  1040 000005E8 75D0                        jne foe_update          ; yes, segment relative, bx hold proper value to put in target_prog_off
  1041                                  
  1042 000005EA 29CB                        sub bx,cx               ; subtract off partition offset
  1043 000005EC 031E[0000]                  add bx,WORD PTR [data_offset] ; compute low word of vector offset
  1044 000005F0 891E[0000]                  mov WORD PTR [target_prog_off],bx ; save it
  1045 000005F4 C706[0200]0000              mov WORD [target_prog_off+2],0    ; zero high word of vector offset
  1046 000005FA A1[0200]                    mov ax,WORD PTR [data_offset+2]   ; get high word of offset
  1047 000005FD 1106[0200]                  adc WORD PTR [target_prog_off+2],ax   ; compute high word of vector offset, with carry
  1048 00000601 C606[0000]01                mov byte [is_ind_call],1       ; set indirect call flag so frame computation bypassed
  1049                                  
  1050                                  foe_retone:
  1051 00000606 B001                        mov al,1                ; return al nonzero to indicate processing of offset done
  1052 00000608 EB02                        jmp SHORT foe_ret
  1053                                  
  1054                                  foe_retzero:
  1055 0000060A 30C0                        xor al,al               ; return al equal to zero to indicate further processing
  1056                                  
  1057                                  foe_ret:
  1058 0000060C 5D                          pop bp
  1059 0000060D 07                          pop es                  ; restore critical register
  1060 0000060E 5E                          pop si
  1061 0000060F 5F                          pop di
  1062 00000610 5A                          pop dx
  1063 00000611 59                          pop cx
  1064 00000612 C3                          ret
  1065                                  fixup_ovl_extdef    ENDP
  1066                                  
  1067                                  ;*****************************
  1068                                  ;* FIXUP_IND_REF_EXTDEF      *
  1069                                  ;*****************************
  1070                                  
  1071                                  ; overlaid public indirectly far referenced by non-overlay class segment
  1072                                  ; change the fixup to a vector
  1073                                  ; upon entry es -> public declaration entry, bh == nonzero if no nonzero
  1074                                  ; target displacement warning given (coming from fixup_ovl_extdef routine)
  1075                                  ; destroys ax,bx
  1076                                  
  1077                                  fixup_ind_ref_extdef    PROC
  1078 00000613 51                          push    cx              ; save critical register
  1079 00000614 52                          push    dx
  1080 00000615 06                          push    es
  1081                                  
  1082                                  ; give warning on nonzero target displacement
  1083 00000616 B001                        mov al,1
  1084 00000618 A2[0000]                    mov [no_fixbyte_flag],al  ; set the flag to indicate fixup bytes at location should be zero
  1085 0000061B A1[0000]                    mov ax,WORD PTR [target_disp]
  1086 0000061E 0B06[0200]                  or  ax,WORD PTR [target_disp+2]
  1087 00000622 7416                        je  fir_zerodisp        ; zero target displacement
  1088 00000624 08FF                        or  bh,bh               ; see if should give warning
  1089 00000626 7512                        jne fir_zerodisp        ; no
  1090                                  
  1091                                  ; nonzero target displacment, give warning
  1092 00000628 06                          push    es              ; save critical registers
  1093 00000629 57                          push    di
  1094 0000062A 26C43E0400                  les di,[es:4]           ; es:di -> symbol name
  1095 0000062F BA[0000]                    mov dx,OFFSET filename wrt DGROUP   ; ds:dx -> filename with problem
  1096 00000632 B84400                      mov ax,NONOVL_SYM_WARN  ; nonoverlayable symbol warning
  1097 00000635 E8(0000)                    call    link_warning
  1098 00000638 5F                          pop di                  ; restore critical registers
  1099 00000639 07                          pop es
  1100                                  
  1101                                  fir_zerodisp:
  1102 0000063A B001                        mov al,1
  1103 0000063C A2[0000]                    mov [is_ind_call],al      ; set indirect call flag
  1104                                  
  1105 0000063F 803E[0000]03                cmp byte [loc],3               ; see if pointer fixup
  1106 00000644 7407                        je  fir_reloc           ; yes
  1107 00000646 803E[0000]02                cmp byte [loc],2               ; see if base fixup
  1108 0000064B 7503                        jne fir_1               ; no, bypass setting relocatable flag
  1109                                  
  1110                                  fir_reloc:
  1111 0000064D A2[0000]                    mov [is_relocatable],al   ; set is relocatable flag
  1112                                  
  1113                                  fir_1:
  1114 00000650 A1[0000]                    mov ax,[ind_segment]
  1115 00000653 A3[0000]                    mov [target_segment],ax   ; set target segment to indirect call table segment
  1116 00000656 8CC2                        mov dx,es               ; save -> public declaration entry in dx
  1117 00000658 A1[0000]                    mov ax,[ind_tbl_segdef]
  1118 0000065B 8EC0                        mov es,ax               ; es -> segdef entry for indirect call table
  1119 0000065D 268B1E0200                  mov bx,[es:2]           ; get low word of offset
  1120 00000662 268B0E0400                  mov cx,[es:4]           ; get high word of offset
  1121 00000667 8EC2                        mov es,dx               ; es -> public declaration entry
  1122 00000669 26A10200                    mov ax,[es:2]           ; get overlaid public number
  1123 0000066D 48                          dec ax                  ; make relative zero
  1124 0000066E 89C2                        mov dx,ax
  1125 00000670 D1E0                        shl ax,1                ; x2
  1126 00000672 01D0                        add ax,dx               ; x3
  1127 00000674 83C010                      add ax,10h              ; adjust for vector paragraph at start of indirect call segment
  1128                                  
  1129 00000677 01D8                        add ax,bx               ; compute target_prog_off value
  1130 00000679 83D100                      adc cx,0                ; carry to high word
  1131                                  
  1132 0000067C A3[0000]                    mov WORD PTR [target_prog_off],ax ; update low word
  1133 0000067F 890E[0200]                  mov WORD PTR [target_prog_off+2],cx   ; update high word
  1134                                  
  1135 00000683 07                          pop es                  ; restore critical register
  1136 00000684 5A                          pop dx
  1137 00000685 59                          pop cx
  1138 00000686 C3                          ret
  1139                                  fixup_ind_ref_extdef    ENDP
  1140                                  
  1141                                  ;*****************************
  1142                                  ;* FIXUP_SEG_REF             *
  1143                                  ;*****************************
  1144                                  
  1145                                  ; overlaid segment far referenced via segment fixup (assume target displacement of zero)
  1146                                  ; OR segment fixup of overlaid segment that is current segment
  1147                                  ; change the fixup to a vector
  1148                                  ; upon entry es -> segment partition entry
  1149                                  ; destroys ax,bx
  1150                                  
  1151                                  fixup_seg_ref   PROC
  1152 00000687 51                          push    cx              ; save critical register
  1153 00000688 52                          push    dx
  1154 00000689 06                          push    es
  1155                                  
  1156 0000068A B001                        mov al,1
  1157 0000068C A2[0000]                    mov [is_ind_call],al      ; set overlaid segment fixup/indirect call flag
  1158 0000068F A2[0000]                    mov [is_relocatable],al   ; set is relocatable flag (always relocatable if pointer)
  1159 00000692 8CC0                        mov ax,es               ; get segment partition entry of segment fixup
  1160 00000694 3B06[0000]                  cmp ax,[data_seg_part]    ; see if matches L?DATA segment partition entry
  1161 00000698 7540                        jne fsr_2               ; no
  1162                                  
  1163                                  ; segment fixup within current segment, zero the segment, make the offset
  1164                                  ; the target displacement
  1165 0000069A 31C0                        xor ax,ax
  1166 0000069C A3[0000]                    mov [target_segment],ax   ; zero target segment
  1167                                  
  1168 0000069F A1[0000]                    mov ax,WORD PTR [target_disp]      ; target displacement goes in targ_prog_off
  1169 000006A2 8B0E[0200]                  mov cx,WORD PTR [target_disp+2]
  1170 000006A6 F606[0000]40                test    BYTE [locat],40h  ; see if fixup self or seg-relative
  1171 000006AB 752B                        jne to_fsr_ret          ; segment relative
  1172                                  
  1173                                  ; self-relative segment fixup within current segment
  1174                                  ; subtract data_rec_offset and data_offset from target displacement, 
  1175                                  ; subtract 1 for low-byte, 2 for offset
  1176                                  
  1177 000006AD C606[0000]00                mov byte [is_relocatable],0    ; zero the relocatable flag (not a segment fixup)
  1178 000006B2 FE06[0000]                  inc byte [is_ind_call]         ; bump flag to 2 to indicate self-relative modification
  1179 000006B6 2B06[0000]                  sub ax,WORD PTR [data_offset]
  1180 000006BA 1B0E[0200]                  sbb cx,WORD PTR [data_offset+2]   ; borrow to high word
  1181 000006BE 2B06[0000]                  sub ax,[data_rec_offset]  ; make target offset relative to location
  1182 000006C2 83D900                      sbb cx,0                ; borrow to high word
  1183 000006C5 83E801                      sub ax,1                ; adjustment alway at least 1 byte
  1184 000006C8 83D900                      sbb cx,0
  1185 000006CB 803E[0000]00                cmp byte [loc],0               ; see if low-byte loc
  1186 000006D0 7466                        je  fsr_ret             ; yes, proper adjustment made
  1187 000006D2 83E801                      sub ax,1                ; subtract one more for offset loc
  1188 000006D5 83D900                      sbb cx,0
  1189                                  
  1190                                  to_fsr_ret:
  1191 000006D8 EB5E                        jmp SHORT fsr_ret
  1192                                  
  1193                                  fsr_2:
  1194 000006DA B001                        mov al,1
  1195 000006DC A2[0000]                    mov [no_fixbyte_flag],al  ; set the flag to indicate fixup bytes at location should be zero
  1196 000006DF A1[0000]                    mov ax,WORD PTR [target_disp]
  1197 000006E2 0B06[0200]                  or  ax,WORD PTR [target_disp+2]
  1198 000006E6 7424                        je  fsr_3               ; zero target displacement
  1199                                  
  1200                                  ; nonzero target displacment, give warning
  1201                                  ; es -> segment partition entry
  1202 000006E8 06                          push    es              ; save critical registers
  1203 000006E9 57                          push    di
  1204                                  
  1205 000006EA 268B3E0400                  mov di,[es:4]           ; get overlay identifer
  1206 000006EF 4F                          dec di                  ; make relative zero
  1207 000006F0 D1E7                        shl di,1                ; convert to work offset
  1208 000006F2 8E06[0000]                  mov es,[master_segblk]
  1209 000006F6 268E05                      mov es,[es:di]          ; es -> master segdef entry
  1210 000006F9 26C43E0800                  les di,[es:8]
  1211 000006FE 83C708                      add di,8                ; es:di -> segment name
  1212                                  
  1213 00000701 BA[0000]                    mov dx,OFFSET filename wrt DGROUP   ; ds:dx -> filename with problem
  1214 00000704 B84300                      mov ax,NONOVL_SEG_WARN  ; nonoverlayable segment warning
  1215 00000707 E8(0000)                    call    link_warning
  1216 0000070A 5F                          pop di                  ; restore critical registers
  1217 0000070B 07                          pop es
  1218                                  
  1219                                  fsr_3:
  1220 0000070C A1[0000]                    mov ax,[segcall_segment]
  1221 0000070F A3[0000]                    mov [target_segment],ax   ; set target segment to segment call table segment
  1222                                  
  1223 00000712 8CC2                        mov dx,es               ; save -> public declaration entry in dx
  1224 00000714 A1[0000]                    mov ax,[segcall_tbl_segdef]
  1225 00000717 8EC0                        mov es,ax               ; es -> segdef entry for segment call table
  1226 00000719 268B1E0200                  mov bx,[es:2]           ; get low word of offset
  1227 0000071E 268B0E0400                  mov cx,[es:4]           ; get high word of offset
  1228 00000723 8EC2                        mov es,dx               ; es -> segment partition entry
  1229                                  
  1230 00000725 26A10400                    mov ax,[es:4]           ; get overlay identifier
  1231 00000729 48                          dec ax                  ; make relative zero
  1232 0000072A 89C2                        mov dx,ax
  1233 0000072C D1E0                        shl ax,1                ; x2
  1234 0000072E 01D0                        add ax,dx               ; x3
  1235 00000730 83C010                      add ax,10h              ; adjust for vector paragraph at start of segment call segment
  1236 00000733 01D8                        add ax,bx               ; compute target_prog_off value
  1237 00000735 83D100                      adc cx,0                ; carry to high word
  1238                                  
  1239                                  fsr_ret:
  1240 00000738 A3[0000]                    mov WORD PTR [target_prog_off],ax ; update low word
  1241 0000073B 890E[0200]                  mov WORD PTR [target_prog_off+2],cx   ; update high word
  1242                                  
  1243 0000073F 07                          pop es                  ; restore critical register
  1244 00000740 5A                          pop dx
  1245 00000741 59                          pop cx
  1246 00000742 C3                          ret
  1247                                  fixup_seg_ref   ENDP
  1248                                  
  1249                                  END
