     1                                  ;*********************************************************************
     2                                  ;*   MLOVL1.ASM                                                      *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          03/12/93                                         *
     6                                  ;*   Model:         Small                                            *
     7                                  ;*   Version:       2.5                                              *
     8                                  ;*   Assembler:     MASM 5.0                                         *
     9                                  ;*   Environment:   MS-DOS 2.x+                                      *
    10                                  ;*                                                                   *
    11                                  ;*   linker overlay pass 1 routines                                  *
    12                                  ;*                                                                   *
    13                                  ;*********************************************************************
    14                                  
    15                                  ;TITLE   WARPLINK mlovl1
    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  chk_seg_ovl_class,chk_pub_in_ovl
    36                                  PUBLIC  proc1_datarec,proc1_fixupp
    37                                  PUBLIC  flush_publics
    38                                  
    39                                  ; variables
    40                                  PUBLIC  curseg_nearovlpub_count,curseg_farovlpub_count,ovlpub_array_seg
    41                                  PUBLIC  ovlpubblk_pos,clarclass_text
    42                                  PUBLIC	lxdata
    43                                  
    44                                  ;*****************************
    45                                  ;* Data begins               *
    46                                  ;*****************************
    47                                  
    48                                  .DATA
    49                                  
    50                                  ;*****************************
    51                                  ;* External declarations     *
    52                                  ;*****************************
    53                                  
    54                                  ; variables
    55                                  EXTRN   name_field:BYTE,filename:BYTE
    56                                  EXTRN   class_name_index:WORD
    57                                  EXTRN   loc:BYTE,target_method:BYTE,target_index:WORD
    58                                  EXTRN   ovl_entry_id:WORD,data_rec_offset:WORD,rec_offset:WORD
    59                                  EXTRN	current_segind:WORD
    60                                  EXTRN	ignore_fixupp_flag:BYTE
    61                                  
    62                                  ; initialized local variables
    63                                  
    64                                  ; word values
    65 00000000 0000                    ovlpubblk_pos   DW  0       ; start position of unused area in overlay public block
    66 00000002 0000                    off_extdef_number   DW  0   ; extdef index of last offset fixup save in overlaid public block
    67 00000004 0000                    seg_extdef_number   DW  0   ; extdef index of last base fixup of overlaid public
    68                                  
    69                                  .DATA?
    70                                  
    71                                  ; uninitialized local variables
    72                                  
    73                                  ; byte values
    74 00000000 ??                      data_seg_overlaid   DB  ?   ; nonzero if overlay class segment partition is overlaid, zero otherwise
    75 00000001 ??                      EVEN
    76 00000002 ??                      off_to_far_flag DB  ?       ; nonzero if offset fixup is for far reference
    77 00000003 ??                      EVEN
    78 00000004 ??                      first_fixup_flag    DB  ?   ; nonzero if first fixup of L?DATA
    79 00000005 ??                      lxdata		DB	?			; holds LEDATA or LIDATA value
    80                                  EVEN
    81                                  
    82                                  ; word values
    83 00000006 ????                    ovl_data_seg    DW  ?       ; segment partition segment of last L?DATA record if overlay class, zero otherwise
    84 00000008 ????                    curseg_nearovlpub_count DW  ?   ; overlaid near public count of current segment
    85 0000000A ????                    curseg_farovlpub_count  DW  ?   ; overlaid far public count of current segment
    86 0000000C ????                    ovlpub_array_seg    DW  ?   ; segment partition entry of current overlaid publics in array
    87                                  
    88 0000000E ????                    segpart_owner   DW  ?       ; segment partition owner of last L?DATA record
    89 00000010 ????                    off_extdef_ptr  DW  ?       ; pointer in overlaid public block to last offset fixup (near) stored
    90 00000012 ????                    off_extdef_segpart  DW  ?   ; segment partition entry of last offset fixup saved to overlaid public block
    91 00000014 ????                    seg_extdef_segpart  DW  ?   ; segment partition entry of last base fixup of overlaid public
    92                                  
    93 00000016 ????                    first_curr_offnum   DW  ?   ; extdef index of first offset fixup of overlaid public in current FIXUPP record
    94 00000018 ????                    first_curr_offptr   DW  ?   ; pointer to first offset fixup of overlaid public in current FIXUPP record
    95 0000001A ????                    first_curr_segnum   DW  ?   ; extdef index of first base fixup of overlaid public in current FIXUPP record
    96 0000001C ????                    first_prev_offnum   DW  ?   ; extdef index of first offset fixup of overlaid public in previous FIXUPP record
    97 0000001E ????                    first_prev_offptr   DW  ?   ; pointer to first offset fixup of overlaid public in previous FIXUPP record
    98 00000020 ????                    first_prev_segnum   DW  ?   ; extdef index of first base fixup of overlaid public in previous FIXUPP record
    99                                  
   100                                  ;*****************************
   101                                  ;* Constant data             *
   102                                  ;*****************************
   103                                  
   104                                  .CONST
   105                                  
   106                                  EVEN
   107 00000000 434C4152494F4E00        clarclass_text  DB  'CLARION',0
   108                                  
   109                                  ;*****************************
   110                                  ;* Code begins               *
   111                                  ;*****************************
   112                                  
   113                                  .CODE
   114                                  
   115                                  ;*****************************
   116                                  ;* External declarations     *
   117                                  ;*****************************
   118                                  
   119                                  ; procedures
   120                                  EXTRN   link_error:NEAR,dos_error:NEAR,load_file:NEAR,link_warning:NEAR
   121                                  EXTRN   alloc_memory:NEAR,error_bx_pos:NEAR
   122                                  EXTRN   caseless_strcmp:NEAR,save_thread:NEAR
   123                                  EXTRN	parse_clipper_symbols:NEAR,clip_sym_fixup:NEAR
   124                                  
   125                                  %IFNDEF DEMO
   126                                  EXTRN   ddl_datarec:NEAR,ddl_fixupp:NEAR
   127                                  %ENDIF
   128                                  
   129                                  ;*****************************
   130                                  ;* CHK_SEG_OVL_CLASS         *
   131                                  ;*****************************
   132                                  
   133                                  ; check new segdef entry class to see if overlay class
   134                                  ; set or reset segdef entry's overlay class flag accordingly
   135                                  ; di -> segdef entry upon entry, name_field holds segment name
   136                                  ; destroys ax,es
   137                                  
   138                                  chk_seg_ovl_class   PROC
   139 00000000 A0[0000]                    mov al,[is_anyovls]
   140                                  
   141                                  %IFNDEF DEMO
   142 00000003 0A06[0000]                  or  al,[any_ddl]          ; see if any overlays specified, or using DLL's
   143                                  %ELSE
   144                                  	or	al,al
   145                                  %ENDIF
   146                                  
   147 00000007 7501                        jne seg_1               ; yes
   148 00000009 C3                          ret                     ; no, just return
   149                                  
   150                                  seg_1:
   151 0000000A 53                          push    bx              ; save critical registers
   152 0000000B 57                          push    di
   153 0000000C 8EC7                        mov es,di               ; es -> segdef entry
   154 0000000E 06                          push    es              ; save -> segdef entry
   155                                  
   156                                  ; get class name from previous lnames record
   157 0000000F A1[0000]                    mov ax,[class_name_index] ; get class name index
   158 00000012 48                          dec ax                  ; make count relative zero
   159 00000013 D1E0                        shl ax,1
   160 00000015 D1E0                        shl ax,1                ; make class name index a doubleword offset into index pointer array
   161 00000017 BF[0000]                    mov di,offset lnames_ent_indptr wrt DGROUP  ; set di to base of lnames index pointer array
   162 0000001A 01C7                        add di,ax               ; di -> proper array element
   163 0000001C C41D                        les bx,[di]             ; -> class name from lnames entry
   164                                  
   165 0000001E 803E[0000]00                cmp byte [is_clarion],0        ; see if clarion flag set
   166 00000023 7405                        je  seg_notclar         ; no
   167 00000025 E86800                      call    cla_ovl_class_check ; check if clarion class and code segment
   168 00000028 EB03                        jmp SHORT seg_2         ; bypass normal class name check
   169                                  
   170                                  seg_notclar:
   171 0000002A E83C00                      call    ovl_class_check ; compare class name against overlay class
   172                                  
   173                                  seg_2:
   174 0000002D 07                          pop es                  ; restore es -> segdef entry
   175 0000002E 26A21C00                    mov [es:28],al          ; re/set the overlay class flag
   176                                  ;***    or  al,al               ; see if overlay class
   177                                  ;***    je  seg_ret             ; no
   178                                  
   179                                  seg_ret:
   180 00000032 5F                          pop di                  ; restore critical registers
   181 00000033 5B                          pop bx
   182 00000034 C3                          ret
   183                                  chk_seg_ovl_class   ENDP
   184                                  
   185                                  ;*****************************
   186                                  ;* CHK_PUB_IN_OVL            *
   187                                  ;*****************************
   188                                  
   189                                  ; check public declaration's segment partition entry to see if in overlay
   190                                  ; set public declaration entry's in overlay flag accordingly
   191                                  ; upon entry es -> pubdef entry
   192                                  ; destroys ax
   193                                  
   194                                  chk_pub_in_ovl  PROC
   195 00000035 803E[0000]00                cmp byte [is_anyovls],0        ; see if any overlays specified
   196 0000003A 7501                        jne pub_1               ; yes
   197 0000003C C3                          ret                     ; no, just return
   198                                  
   199                                  pub_1:
   200 0000003D 06                          push    es              ; save es -> pubdef entry
   201 0000003E 268E060000                  mov es,[es:0]           ; es -> segment partition entry
   202 00000043 26A00F00                    mov al,[es:15]          ; get overlay flag of segment partition entry
   203 00000047 2480                        and al,80h              ; save only overlay flag bit
   204 00000049 D0C0                        rol al,1                ; get high bit value in low bit
   205                                  
   206                                  ; check if overlay flag set, if so bypass checks in case of pass 2 usage, so
   207                                  ; invalid master segdef entry value pointer doesn't screw up overlay class bit
   208 0000004B 750E                        jne pub_ovl             ; overlay flag bit set, guaranteed overlay class
   209                                  
   210 0000004D 268E060400                  mov es,[es:4]           ; es -> master segdef entry
   211 00000052 268A261C00                  mov ah,[es:28]          ; get overlay class flag
   212 00000057 08E4                        or  ah,ah               ; see if overlay class
   213 00000059 7402                        je  pub_2               ; no
   214                                  
   215                                  pub_ovl:
   216 0000005B B408                        mov ah,8                ; overlay class, get proper bit value in ah
   217                                  
   218                                  pub_2:
   219 0000005D 07                          pop es                  ; restore es -> pubdef entry
   220 0000005E 2608260F00                  or  [es:15],ah          ; re/set the overlay class bit
   221 00000063 2608060F00                  or  [es:15],al          ; re/set the overlaid flag bit
   222                                  
   223                                  pub_ret:
   224 00000068 C3                          ret
   225                                  chk_pub_in_ovl  ENDP
   226                                  
   227                                  ;*****************************
   228                                  ;* OVL_CLASS_CHECK           *
   229                                  ;*****************************
   230                                  
   231                                  ; check the class name -> by es:bx (prior to doubleword adjustment)
   232                                  ; against the overlay class specified in the linker command line
   233                                  ; destroys ax,bx,di
   234                                  ; returns al==1 if overlay class, 0 if not overlay class
   235                                  
   236                                  ovl_class_check PROC
   237 00000069 83C308                      add bx,8                ; adjust bx past 2 doubleword pointers
   238 0000006C BF[0000]                    mov di,OFFSET ovl_class wrt DGROUP  ; ds:di -> overlay class name
   239 0000006F 30C0                        xor al,al
   240 00000071 3806[0000]                  cmp [exact_ovl_class],al  ; see if exact match flag set
   241 00000075 7513                        jne chk_compare         ; yes, bypass suffix setup
   242                                  
   243                                  ; point to check string null terminator
   244                                  chk_loop1:
   245 00000077 263807                      cmp [es:bx],al
   246 0000007A 7403                        je  chk_2               ; at null terminator
   247 0000007C 43                          inc bx
   248 0000007D EBF8                        jmp SHORT chk_loop1     ; no at null terminator yet, keep looking
   249                                  
   250                                  ; step the check string back one char for every char in target string
   251                                  ; this will allow successful matches for a target string suffix
   252                                  chk_2:
   253 0000007F 3805                        cmp [di],al             ; see if at null terminator
   254 00000081 7404                        je  chk_3               ; yes, check string now pointing at possible suffix
   255 00000083 47                          inc di                  ; bump to next char
   256 00000084 4B                          dec bx                  ; back up one char of check string
   257 00000085 EBF8                        jmp SHORT chk_2         ; loop back
   258                                  
   259                                  chk_3:
   260 00000087 BF[0000]                    mov di,OFFSET ovl_class wrt DGROUP  ; restore di -> overlay class name
   261                                  
   262                                  ; perform a caseless string compare on the names
   263                                  chk_compare:
   264 0000008A E8(0000)                    call    caseless_strcmp ; al return 0 if match, 1 if no match
   265 0000008D 3401                        xor al,1                ; flip the match bit
   266 0000008F C3                          ret
   267                                  ovl_class_check ENDP
   268                                  
   269                                  ;*****************************
   270                                  ;* CLA_OVL_CLASS_CHECK       *
   271                                  ;*****************************
   272                                  
   273                                  ; check if Clarion overlay class, class 'CLARION', segment prefix is '_CODE'
   274                                  ; upon entry es:bx -> class name (prior to doubleword adjustment)
   275                                  ; destroys ax,bx,di
   276                                  ; returns al==1 if overlay class, 0 if not overlay class
   277                                  
   278                                  cla_ovl_class_check PROC
   279 00000090 30C0                    	xor	al,al
   280 00000092 3806[0000]                  cmp	[any_ddl],al			; see if using DDL's
   281 00000096 7409                    	je	coc_2				; no
   282 00000098 3806[0000]                  cmp [obj_ovl_flag],al		; see if in overlay
   283 0000009C 7403                    	je	coc_2				; no, do regular check
   284 0000009E B001                    	mov	al,1
   285 000000A0 C3                      	ret						; return al==1 as overlay class
   286                                  
   287                                  ; cheesy, but easy and quick, check for '_CODE' prefix on segment name
   288                                  coc_2:
   289 000000A1 BF[0000]                    mov di,OFFSET name_field wrt DGROUP ; ds:di -> segment name
   290 000000A4 803D5F                      cmp BYTE PTR [di],'_'
   291 000000A7 7524                        jne cla_nomatch
   292 000000A9 807D0143                    cmp BYTE PTR [di+1],'C'
   293 000000AD 751E                        jne cla_nomatch
   294 000000AF 807D024F                    cmp BYTE PTR [di+2],'O'
   295 000000B3 7518                        jne cla_nomatch
   296 000000B5 807D0344                    cmp BYTE PTR [di+3],'D'
   297 000000B9 7512                        jne cla_nomatch
   298 000000BB 807D0445                    cmp BYTE PTR [di+4],'E'
   299 000000BF 750C                        jne cla_nomatch
   300                                  
   301 000000C1 83C308                      add bx,8                ; adjust bx past 2 doubleword pointers
   302 000000C4 BF[0000]                    mov di,OFFSET clarclass_text wrt DGROUP ; ds:di -> overlay class name
   303                                  
   304                                  ; perform a caseless string compare on the names
   305 000000C7 E8(0000)                    call    caseless_strcmp ; al return 0 if match, 1 if no match
   306 000000CA 3401                        xor al,1                ; flip the match bit
   307 000000CC C3                          ret
   308                                  
   309                                  cla_nomatch:
   310 000000CD 30C0                        xor al,al               ; flag no match
   311 000000CF C3                          ret
   312                                  
   313                                  cla_ovl_class_check ENDP
   314                                  
   315                                  ;*****************************
   316                                  ;* PROC1_DATAREC             *
   317                                  ;*****************************
   318                                  
   319                                  ; pass 1 L?DATA record processing for overlays
   320                                  ; upon entry cx=record length,bp=buffer_end
   321                                  ; si -> first byte of record past record length word
   322                                  ; set ovl_data_seg to partition segment if overlay class, reset otherwise
   323                                  ; if overlay class, set data_seg_overlaid if segment is overlaid, reset otherwise
   324                                  ; destroys ax,bx,dx,di,es
   325                                  ; updates si,cx
   326                                  
   327                                  proc1_datarec   PROC
   328 000000D0 C606[0000]00            	mov	byte [ignore_fixupp_flag],0	; flag not to ignore following fixup
   329                                  %IFNDEF DEMO
   330 000000D5 803E[0000]00                cmp byte [any_ddl],0           ; see if using DDL's
   331 000000DA 7403                        je  data_noddl          ; no
   332 000000DC E9(0000)                    jmp NEAR PTR ddl_datarec    ; transfer to DDL processing code
   333                                  %ENDIF
   334                                  
   335                                  data_noddl:
   336 000000DF A2[0500]                	mov	[lxdata],al			; save LEDATA or LIDATA type
   337 000000E2 89F3                        mov bx,si               ; keep offset pointer to index in case of error
   338 000000E4 26AC                        es lodsb   ; get first byte of segment index
   339 000000E6 49                          dec cx                  ; decrement record length to parse
   340 000000E7 39EE                        cmp si,bp               ; check boundary conditions
   341 000000E9 7203                        jb  data_1              ; okay
   342 000000EB E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   343                                  
   344                                  data_1:
   345 000000EE 3C80                        cmp al,80h              ; check if high bit set
   346 000000F0 7217                        jb  data_3              ; no, only 1 byte index
   347                                  
   348                                  ; two byte index, dh contains high-order byte with high bit set
   349 000000F2 740B                        je  data_2              ; if greater than 0x80 then segment index > 255, out of bounds
   350                                  
   351                                  data_bad_segind:
   352 000000F4 88C1                        mov cl,al               ; get value in cl
   353 000000F6 BA[0000]                    mov dx,OFFSET filename wrt DGROUP
   354 000000F9 B80900                      mov ax,SEGDEF_VAL_ERR   ; segment index greater than 255 maximum, or higher than count of segdef records
   355 000000FC E9(0000)                    jmp NEAR PTR error_bx_pos   ; transfer control to error handler
   356                                  
   357                                  data_2:
   358 000000FF 26AC                        es lodsb   ; get second byte of segment index
   359 00000101 49                          dec cx                  ; decrement record length to parse
   360 00000102 39EE                        cmp si,bp               ; check boundary conditions
   361 00000104 7203                        jb  data_3              ; okay
   362 00000106 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   363                                  
   364                                  ; al contains segment index value
   365                                  data_3:
   366 00000109 FEC8                        dec al                  ; make segment index value relative zero
   367 0000010B 30E4                        xor ah,ah               ; zap high byte
   368 0000010D A3[0000]                	mov	[current_segind],ax	; save to memory variable for Clipper compression use
   369                                  
   370 00000110 E8(0000)                	call	parse_clipper_symbols	; parse for clipper symbol table compression, if indicated
   371                                  
   372 00000113 89C2                        mov dx,ax               ; save segment index in dx (dl)
   373 00000115 BB[0000]                    mov bx,offset seg_defent_indptr wrt DGROUP  ; set bx to base of segment index pointer array
   374 00000118 D1E0                        shl ax,1                ; make segment index value a word offset into index pointer array
   375 0000011A 01C3                        add bx,ax               ; bx -> proper segment index array element
   376 0000011C 8E07                        mov es,[bx]             ; es -> segdef entry
   377                                  
   378 0000011E 803E[0000]00                cmp byte [is_clarion],0        ; see if clarion switch set
   379 00000123 740A                        je  data_chkovl         ; no
   380 00000125 803E[0000]00                cmp byte [obj_ovl_flag],0      ; see if in overlay
   381 0000012A 7403                        je  data_chkovl         ; no
   382                                  
   383 0000012C E85000                      call    proc1_clar_data ; process possible overlaid Clarion LEDATA
   384                                  
   385                                  data_chkovl:
   386 0000012F 26A01C00                    mov al,[es:28]          ; get overlay flag value of segment
   387 00000133 08C0                        or  al,al               ; see if set
   388 00000135 750D                        jne data_4              ; yes, this is an overlay class segment
   389                                  
   390                                  ; not overlay class
   391                                  data_notovl:
   392 00000137 26A11800                    mov ax,[es:24]
   393 0000013B A3[0E00]                    mov [segpart_owner],ax    ; save segment partition entry owner
   394 0000013E 31C0                        xor ax,ax
   395 00000140 88C2                        mov dl,al               ; reset overlaid data segment flag
   396 00000142 EB11                        jmp SHORT data_setseg   ; zero the overlay data segment variable
   397                                  
   398                                  ; get last segment partition in segdef, this will be the owner of the overlaid code
   399                                  data_4:
   400 00000144 26A11800                    mov ax,[es:24]          ; get last segment partition entry
   401 00000148 A3[0E00]                    mov [segpart_owner],ax    ; save segment partition entry owner
   402 0000014B 8EC0                        mov es,ax               ; es -> segment partition entry
   403 0000014D 268A160F00                  mov dl,[es:15]
   404 00000152 80E280                      and dl,80h              ; get overlaid status flag
   405                                  
   406                                  data_setseg:
   407 00000155 8816[0000]                  mov [data_seg_overlaid],dl    ; re/set the overlaid data segment flag
   408 00000159 A3[0600]                    mov [ovl_data_seg],ax     ; set the overlay data segment to segment partition entry, zero if not overlay class
   409                                  
   410                                  ; This crap is necessary because Clipper 5.0 writes fixups in descending
   411                                  ; instead of ascending order and then will split up a base:offset reference
   412                                  ; to a single EXTDEF across multiple FIXUPPs.  Keeping track of the first
   413                                  ; reference in the previous record and then matching on it against offsets
   414                                  ; will catch this condition.
   415 0000015C A1[1600]                    mov ax,[first_curr_offnum]    ; transfer old first current to first previous variables
   416 0000015F A3[1C00]                    mov [first_prev_offnum],ax
   417 00000162 A1[1A00]                    mov ax,[first_curr_segnum]
   418 00000165 A3[2000]                    mov [first_prev_segnum],ax
   419 00000168 A1[1800]                    mov ax,[first_curr_offptr]
   420 0000016B A3[1E00]                    mov [first_prev_offptr],ax
   421                                  
   422 0000016E 31C0                        xor ax,ax               ; re-init fixup flags and variables
   423 00000170 A3[1600]                    mov [first_curr_offnum],ax
   424 00000173 A3[1A00]                    mov [first_curr_segnum],ax
   425 00000176 A3[1800]                    mov [first_curr_offptr],ax
   426                                  
   427                                  ; 10/20/92
   428                                  ;    mov seg_extdef_number,ax
   429                                  ;    mov off_extdef_number,ax
   430                                  
   431 00000179 FEC0                        inc al
   432 0000017B A2[0400]                    mov [first_fixup_flag],al
   433 0000017E C3                          ret
   434                                  proc1_datarec   ENDP
   435                                  
   436                                  ;*****************************
   437                                  ;* PROC1_CLAR_DATA           *
   438                                  ;*****************************
   439                                  
   440                                  ; process possible Clarion overlaid data segment
   441                                  ; upon entry cx=record length,bp=buffer_end
   442                                  ; es-> segdef entry owner of L?DATA record
   443                                  ; si -> enumerated offset of L?DATA record, within i/o buffer
   444                                  ; dl holds segment index, relative zero
   445                                  ; destroys ax,bx,dx,di
   446                                  ; updates si,cx
   447                                  
   448                                  proc1_clar_data PROC
   449 0000017F 06                          push    es              ; save critical register
   450 00000180 8E06[0000]                  mov es,[buffer_base]      ; es:si -> enumerated offset of L?DATA record
   451                                  
   452                                  ; get the enumerated data offset, if not zero, ignore
   453 00000184 26AC                        es lodsb   ; get low byte of data offset
   454 00000186 49                          dec cx                  ; decrement record length to parse
   455 00000187 39EE                        cmp si,bp               ; check boundary conditions
   456 00000189 7203                        jb  data_high           ; okay
   457 0000018B E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   458                                  data_high:
   459 0000018E 268A24                      mov ah,[es:si]          ; get high byte of data offset
   460 00000191 46                          inc si
   461 00000192 49                          dec cx                  ; decrement record length to parse
   462 00000193 39EE                        cmp si,bp               ; check boundary conditions
   463 00000195 7203                        jb  data_nowrap         ; okay
   464 00000197 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   465                                  data_nowrap:
   466 0000019A 07                          pop es                  ; restore es -> segdef entry
   467 0000019B 09C0                        or  ax,ax               ; see if nonzero data offset (not first LEDATA)
   468 0000019D 751C                        jne pcd_ret             ; nonzero, ignore
   469                                  
   470                                  ; in overlay and clarion switch set, determine if Clarion _DT or _DAT segment
   471                                  ; (class 'CLARION', private segment, name prefixed with '_DT' or '_DAT')
   472                                  ; if so, track the segment size, zero the length entry
   473 0000019F 26A01A00                    mov al,[es:26]          ; get ACBP byte
   474 000001A3 241C                        and al,1ch              ; get combine value
   475 000001A5 7514                        jne pcd_ret             ; not a private segment
   476                                  
   477 000001A7 06                          push    es              ; save es -> segdef entry
   478 000001A8 26C41E0C00                  les bx,[es:12]          ; es:bx -> class name
   479 000001AD 83C308                      add bx,8                ; adjust bx past 2 doubleword pointers
   480 000001B0 BF[0000]                    mov di,OFFSET clarclass_text wrt DGROUP ; ds:di -> overlay class name
   481                                  
   482                                  ; perform a caseless string compare on the names
   483 000001B3 E8(0000)                    call    caseless_strcmp ; al return 0 if match, 1 if no match
   484 000001B6 07                          pop es                  ; restore es -> segdef entry
   485 000001B7 08C0                        or  al,al               ; see if match
   486 000001B9 7401                        je  pcd_isclar          ; yes
   487                                  
   488                                  pcd_ret:
   489 000001BB C3                          ret
   490                                  
   491                                  pcd_isclar:
   492                                  
   493 000001BC 89D0                        mov ax,dx               ; segment index relative zero in ax (al holds value, ah==0)
   494 000001BE B203                        mov dl,3
   495 000001C0 F6F2                        div dl                  ; get multiple clarion segment grouping (_dt, _dat, _code) count
   496 000001C2 88C2                        mov dl,al               ; save clarion segment grouping count
   497                                  
   498 000001C4 A1[0000]                    mov ax,[ovl_entry_id]     ; get entry overlaid code id
   499 000001C7 01D0                        add ax,dx               ; adjust for multiple clarion segment grouping count, if any
   500                                  
   501                                  ; since no adjustment for current entry from ovl_entry_id, relative zero
   502                                  ; adjustment has effectively been made
   503 000001C9 D1E0                        shl ax,1                ; x2
   504 000001CB D1E0                        shl ax,1                ; x4
   505 000001CD A3[0000]                    mov [ovl_data_id],ax      ; save as current overlaid data identifier
   506 000001D0 26A10600                    mov ax,[es:6]           ; get segment size
   507 000001D4 8CDF                        mov di,ds               ; save critical register
   508 000001D6 26C51E0800                  lds bx,[es:8]
   509 000001DB 83C308                      add bx,8                ; ds:bx -> segment name
   510 000001DE 803F5F                      cmp BYTE PTR [bx],'_'
   511 000001E1 751E                        jne pcd_nomatch         ; no match against clarion data segment name
   512 000001E3 807F0144                    cmp BYTE PTR [bx+1],'D'
   513 000001E7 7518                        jne pcd_nomatch
   514 000001E9 807F0254                    cmp BYTE PTR [bx+2],'T' ; see if _DT segment
   515 000001ED 7415                        je  pcd_dt_seg          ; yes
   516 000001EF 807F0241                    cmp BYTE PTR [bx+2],'A' ; see if _DA[T] segment (assume 'T')
   517 000001F3 750C                        jne pcd_nomatch         ; no, no match
   518                                  
   519 000001F5 8EDF                        mov ds,di               ; restore ds -> WarpLink data
   520 000001F7 A3[0000]                    mov [_dat_seg_size],ax    ; save _DAT segment size
   521 000001FA 8306[0000]02                add word [ovl_data_id],2       ; bump to next entry (two entries/module data)
   522 000001FF EB08                        jmp SHORT pcd_2
   523                                  
   524                                  pcd_nomatch:
   525 00000201 8EDF                        mov ds,di               ; restore ds -> WarpLink data
   526 00000203 C3                          ret
   527                                  
   528                                  pcd_dt_seg:
   529 00000204 8EDF                        mov ds,di               ; restore ds -> WarpLink data
   530 00000206 A3[0000]                    mov [_dt_seg_size],ax     ; save _DT segment size
   531                                  
   532                                  ; save segment length in overlay data block
   533                                  pcd_2:
   534 00000209 06                          push    es              ; save -> segdef entry
   535 0000020A 51                          push    cx              ; save critical registers
   536 0000020B 52                          push    dx
   537 0000020C 8B16[0000]                  mov dx,[ovl_data_id]      ; get data overlay identifier
   538 00000210 A1[0000]                    mov ax,[data_ovlblk_ptr]  ; get initial data overlay block
   539 00000213 8EC0                        mov es,ax               ; es -> block, if exists
   540 00000215 09C0                        or  ax,ax               ; check if any blocks were previously allocated
   541 00000217 7516                        jne pcd_3               ; yes
   542                                  
   543                                  ; make initial data overlay block allocation
   544 00000219 BB1000                      mov bx,DATA_OVLBLK_SIZE ; number of paragraphs to allocate
   545 0000021C E8(0000)                    call    alloc_memory    ; get memory for block allocation
   546 0000021F A3[0000]                    mov [data_ovlblk_ptr],ax
   547                                  
   548                                  pcd_zeroblk:
   549 00000222 8EC0                        mov es,ax               ; es -> data block
   550 00000224 31C0                        xor ax,ax
   551 00000226 B90001                      mov cx,DATA_OVLBLK_BYSIZE   ; size of block to zero in bytes
   552 00000229 D1E9                        shr cx,1                ; convert to words
   553 0000022B 89C7                        mov di,ax
   554 0000022D F3AB                        rep stosw               ; zero block
   555                                  
   556                                  pcd_3:
   557 0000022F 81FAFC00                    cmp dx,252              ; see entry is in this block (126 word entries)
   558 00000233 721E                        jb  pcd_inblk           ; yes
   559 00000235 81EAFC00                    sub dx,252              ; adjust past this block
   560 00000239 26A10000                    mov ax,[es:0]           ; get pointer to next block
   561 0000023D 8CC3                        mov bx,es               ; save -> to old block in case no new
   562 0000023F 8EC0                        mov es,ax
   563 00000241 09C0                        or  ax,ax               ; see if block exists
   564 00000243 75EA                        jne pcd_3               ; yes
   565                                  
   566                                  ; block doesn't exist
   567 00000245 8EC3                        mov es,bx               ; restore es -> old block
   568 00000247 BB1000                      mov bx,DATA_OVLBLK_SIZE ; number of paragraphs to allocate
   569 0000024A E8(0000)                    call    alloc_memory    ; get memory for block allocation
   570 0000024D 26A30000                    mov [es:0],ax           ; save pointer to new block in old block
   571 00000251 EBCF                        jmp SHORT pcd_zeroblk   ; zero it out and continue
   572                                  
   573                                  pcd_inblk:
   574 00000253 F706[0000]0200              test    word [ovl_data_id],2   ; see if _DT or _DAT segment
   575 00000259 7405                        je  pcd_4               ; _DT segment
   576 0000025B A1[0000]                    mov ax,[_dat_seg_size]    ; get _DAT segment size
   577 0000025E EB03                        jmp SHORT pcd_5
   578                                  
   579                                  pcd_4:
   580 00000260 A1[0000]                    mov ax,[_dt_seg_size]     ; get _DT segment size
   581                                  
   582                                  pcd_5:
   583 00000263 89D3                        mov bx,dx               ; es:bx -> overlaid data block entry to place segment size
   584 00000265 26894702                    mov [es:bx+2],ax        ; save segment size, adjusting for system info word
   585                                  
   586 00000269 5A                          pop dx                  ; restore critical register
   587 0000026A 59                          pop cx
   588 0000026B 07                          pop es                  ; restore es -> segdef entry
   589                                  
   590                                  ; zero the segment length of the entry
   591 0000026C 31C0                        xor ax,ax
   592 0000026E 26A30600                    mov [es:6],ax
   593                                  
   594 00000272 C3                          ret
   595                                  proc1_clar_data ENDP
   596                                  
   597                                  ;*****************************
   598                                  ;* PROC1_FIXUPP              *
   599                                  ;*****************************
   600                                  
   601                                  ; pass 1 FIXUPP record processing for overlays
   602                                  ; upon entry cx=record length,bp=buffer_end
   603                                  ; si -> first byte of record past record length word
   604                                  ; destroys ax,bx,dx,di
   605                                  ; updates si,cx
   606                                  
   607                                  proc1_fixupp    PROC
   608                                  %IFNDEF DEMO
   609 00000273 803E[0000]00                cmp byte [any_ddl],0           ; see if using DDL's
   610 00000278 7403                        je  fix_2               ; no
   611 0000027A E9(0000)                    jmp NEAR PTR ddl_fixupp ; transfer to DDL processing code
   612                                  %ENDIF
   613                                  
   614                                  ; track fixups of extdefs which are overlaid or unresolved
   615                                  ; if segment is overlaid, track count of segment fixups as well
   616                                  fix_2:
   617 0000027D 268A04                      mov al,[es:si]          ; get first byte of either thread or fixup field
   618 00000280 2480                        and al,80h              ; check fixup field, high bit set
   619 00000282 7509                        jne fix_fixup           ; yes, fixup field
   620                                  
   621                                  ; thread field in fixupp record
   622 00000284 E8(0000)                    call    save_thread     ; save the thread field in case it is needed
   623 00000287 83F901                      cmp cx,1                ; check if at checksum byte
   624 0000028A 77F1                        ja  fix_2               ; no, keep parsing fixupp record
   625                                  
   626                                  pf_ret:
   627 0000028C C3                          ret                     ; yes, done
   628                                  
   629                                  fix_fixup:
   630 0000028D 803E[0000]00            	cmp	byte [ignore_fixupp_flag],0	; see if should ignore fixupp record
   631 00000292 75F8                    	jne	pf_ret				; yes
   632 00000294 26AC                        es lodsb   ; get low byte of locat field
   633 00000296 49                          dec cx                  ; decrement record length to parse
   634 00000297 39EE                        cmp si,bp               ; check boundary conditions
   635 00000299 7203                        jb  fix_3               ; okay
   636 0000029B E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   637                                  fix_3:
   638 0000029E 268A24                      mov ah,[es:si]          ; get high byte of locat field
   639 000002A1 46                          inc si
   640 000002A2 49                          dec cx                  ; decrement record length to parse
   641 000002A3 39EE                        cmp si,bp               ; check boundary conditions
   642 000002A5 7203                        jb  fix_4               ; okay
   643 000002A7 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   644                                  fix_4:
   645 000002AA 88C2                        mov dl,al
   646 000002AC 241C                        and al,1ch              ; get loc field
   647 000002AE D0E8                        shr al,1
   648 000002B0 D0E8                        shr al,1                ; make loc value relative zero
   649 000002B2 A2[0000]                    mov [loc],al              ; save loc value
   650                                  
   651 000002B5 8826[0000]                  mov BYTE PTR [data_rec_offset],ah ; save bit 7-0 of data record offset in locat high byte
   652 000002B9 80E203                      and dl,3                ; get bit 9-8 of data record offset in locat low byte
   653 000002BC 8816[0100]                  mov BYTE PTR [data_rec_offset+1],dl   ; and save it
   654                                  
   655                                  ; check if need to do clipper symbol table fixup code
   656 000002C0 E8(0000)                	call	clip_sym_fixup
   657                                  
   658 000002C3 268A14                      mov dl,[es:si]          ; get fix dat field
   659 000002C6 46                          inc si
   660 000002C7 49                          dec cx                  ; decrement record length to parse
   661 000002C8 39EE                        cmp si,bp               ; check boundary conditions
   662 000002CA 7203                        jb  fix_5               ; okay
   663 000002CC E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   664                                  fix_5:
   665 000002CF 88D0                        mov al,dl               ; get fix dat field
   666 000002D1 A880                        test    al,80h          ; check if thread field for frame (fbit)
   667 000002D3 751D                        jne fix_7               ; yes
   668                                  
   669                                  ; no thread field for frame
   670 000002D5 2470                        and al,70h              ; get frame field in al
   671 000002D7 3C20                        cmp al,20h              ; see if index specified for this frame
   672 000002D9 7717                        ja  fix_7               ; no
   673                                  
   674                                  ; index specified for this field
   675 000002DB 26AC                        es lodsb   ; get frame datum first byte
   676 000002DD 49                          dec cx                  ; decrement record length to parse
   677 000002DE 39EE                        cmp si,bp               ; check boundary conditions
   678 000002E0 7203                        jb  fix_6               ; okay
   679 000002E2 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   680                                  fix_6:
   681 000002E5 3C80                        cmp al,80h              ; see if two byte field
   682 000002E7 7209                        jb  fix_7               ; no
   683 000002E9 46                          inc si                  ; scan past frame datum second byte
   684 000002EA 49                          dec cx                  ; decrement record length to parse
   685 000002EB 39EE                        cmp si,bp               ; check boundary conditions
   686 000002ED 7203                        jb  fix_7               ; okay
   687 000002EF E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   688                                  
   689                                  fix_7:
   690 000002F2 88D0                        mov al,dl               ; get fix dat field
   691 000002F4 A808                        test    al,8            ; check if thread field for target (tbit)
   692 000002F6 752A                        jne fix_thrdtarg        ; yes
   693                                  
   694                                  ; no thread field for target
   695 000002F8 30E4                        xor ah,ah               ; zap high byte
   696 000002FA 26AC                        es lodsb   ; get target datum first byte
   697 000002FC 49                          dec cx                  ; decrement record length to parse
   698 000002FD 39EE                        cmp si,bp               ; check boundary conditions
   699 000002FF 7203                        jb  fix_8               ; okay
   700 00000301 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   701                                  fix_8:
   702 00000304 3C80                        cmp al,80h              ; see if two byte field
   703 00000306 720E                        jb  fix_9               ; no
   704 00000308 247F                        and al,7fh              ; strip high bit
   705 0000030A 88C4                        mov ah,al               ; move value to high byte
   706                                  
   707 0000030C 26AC                        es lodsb   ; get target datum second byte
   708 0000030E 49                          dec cx                  ; decrement record length to parse
   709 0000030F 39EE                        cmp si,bp               ; check boundary conditions
   710 00000311 7203                        jb  fix_9               ; okay
   711 00000313 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   712                                  
   713                                  fix_9:
   714 00000316 A3[0000]                    mov [target_index],ax     ; target index, if any
   715 00000319 88D0                        mov al,dl               ; get fix dat field
   716 0000031B 2403                        and al,3                ; break out targt field
   717 0000031D A2[0000]                    mov [target_method],al    ; target method is the targt field
   718 00000320 EB1B                        jmp SHORT fix_10        ; bypass target thread field code
   719                                  
   720                                  ; thread field for target
   721                                  fix_thrdtarg:
   722 00000322 2403                        and al,3                ; get targt field value in al
   723 00000324 30E4                        xor ah,ah               ; zap high byte
   724 00000326 BB[0000]                    mov bx,OFFSET target_thrd_meth wrt DGROUP   ; bx -> target thread method array base
   725 00000329 01C3                        add bx,ax               ; bx -> proper byte array element
   726 0000032B 8A1F                        mov bl,[bx]             ; get target method
   727 0000032D 881E[0000]                  mov [target_method],bl    ; save to memory variable
   728                                  
   729 00000331 D1E0                        shl ax,1                ; convert to word offset
   730 00000333 BB[0000]                    mov bx,OFFSET target_thrd_index wrt DGROUP  ; bx -> target thread index array base
   731 00000336 01C3                        add bx,ax               ; bx -> proper word array element
   732 00000338 8B07                        mov ax,[bx]             ; get target index
   733 0000033A A3[0000]                    mov [target_index],ax     ; save to memory variable
   734                                  
   735                                  fix_10:
   736 0000033D 88D0                        mov al,dl               ; get fix dat field
   737 0000033F 2404                        and al,4                ; get P bit field
   738 00000341 7512                        jne fix_ovlchk          ; P bit set, no target displacement field
   739                                  
   740                                  ; P bit is zero, get target displacement field
   741 00000343 46                          inc si                  ; scan past low byte of target displacement
   742 00000344 49                          dec cx                  ; decrement record length to parse
   743 00000345 39EE                        cmp si,bp               ; check boundary conditions
   744 00000347 7203                        jb  fix_11              ; okay
   745 00000349 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   746                                  fix_11:
   747 0000034C 46                          inc si                  ; scan past high byte of target displacement
   748 0000034D 49                          dec cx                  ; decrement record length to parse
   749 0000034E 39EE                        cmp si,bp               ; check boundary conditions
   750 00000350 7203                        jb  fix_ovlchk			; okay
   751 00000352 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   752                                  
   753                                  ; check if the owner segment is overlaid
   754                                  ; if so and segment is overlaid, bump relocation count for partition entry
   755                                  fix_ovlchk:
   756 00000355 803E[0000]00                cmp byte [data_seg_overlaid],0
   757 0000035A 741C                        je  fix_chk_targ        ; segment not overlaid, don't track segment fixups
   758 0000035C 8CC3                        mov bx,es               ; save -> i/o buffer
   759 0000035E A1[0600]                    mov ax,[ovl_data_seg]
   760 00000361 8EC0                        mov es,ax               ; es -> segment partition entry
   761 00000363 803E[0000]02                cmp byte [loc],2               ; see if segment (base) fixup
   762 00000368 7407                        je  fix_13              ; yes, increment count of relocation items
   763 0000036A 803E[0000]03                cmp byte [loc],3               ; see if pointer (segment:offset) fixup
   764 0000036F 7505                        jne fix_14              ; no, not a segment fixup
   765                                  
   766                                  fix_13:
   767 00000371 26FF060000                  inc WORD PTR [es:0]     ; increment count of relocation items
   768                                  
   769                                  ; check for offset or seg:off fixups using an EXTDEF that is in an overlay
   770                                  fix_14:
   771 00000376 8EC3                        mov es,bx               ; restore es -> i/o buffer
   772                                  
   773                                  fix_chk_targ:
   774 00000378 803E[0000]02                cmp byte [target_method],2     ; see if extdef target (target_method doesn't have bit 2)
   775 0000037D 7403                        je  fix_14a             ; yes
   776                                  
   777                                  to_next_fix3:
   778 0000037F E9CB01                      jmp NEAR PTR next_fix   ; no, continue checking fixups
   779                                  
   780                                  ; fixup has EXTDEF target
   781                                  fix_14a:
   782 00000382 A0[0000]                    mov al,[loc]              ; get fixup type
   783 00000385 08C0                        or  al,al
   784 00000387 74F6                        je  to_next_fix3        ; lobyte type, ignore
   785                                  
   786 00000389 30C0                        xor al,al
   787 0000038B A2[0200]                    mov [off_to_far_flag],al  ; initialize offset is far flag
   788                                  
   789                                  ; check if EXTDEF is either overlaid class or unknown
   790 0000038E A1[0000]                    mov ax,[target_index]     ; get target index (extdef index)
   791 00000391 48                          dec ax                  ; make ax relative zero offset
   792 00000392 D1E0                        shl ax,1                ; convert ax to word offset
   793 00000394 89C7                        mov di,ax               ; save in di
   794 00000396 8CC2                        mov dx,es               ; save -> i/o buffer
   795 00000398 BB[0000]                    mov bx,OFFSET ext_defent_indptr wrt DGROUP  ; set bx to base of pubdef declarations entry address array
   796 0000039B 01C3                        add bx,ax               ; bx -> array element holding pubdef declarations entry address
   797 0000039D 8B1F                        mov bx,[bx]             ; bx -> pubdef declarations entry of referenced EXTDEF in FIXUPP record
   798                                  ;***    or  bx,bx               ; check if zero (local)
   799                                  ;***    je  nosave_ref          ; yes, don't vector locals
   800 0000039F 8EC3                        mov es,bx               ; es -> pubdef declarations entry
   801                                  
   802 000003A1 26A00F00                    mov al,[es:15]
   803 000003A5 88C4                        mov ah,al
   804                                  ;***    and ah,4                ; see if local public
   805                                  ;***    jne nosave_ref          ; yes, don't vector locals
   806                                  
   807 000003A7 26800E0E0040                or  BYTE PTR [es:14],40h    ; set used in fixup flag
   808                                  
   809 000003AD 803E[0400]00                cmp byte [first_fixup_flag],0  ; see if first fixup
   810 000003B2 742A                        je  fix_15              ; no
   811 000003B4 C606[0400]00                mov byte [first_fixup_flag],0  ; reset first fixup flag
   812 000003B9 8A1E[0000]                  mov bl,[loc]
   813 000003BD 80FB01                      cmp bl,1                ; see if offset
   814 000003C0 7414                        je  fix_locoff          ; yes
   815 000003C2 80FB05                      cmp bl,5                ; see if alternate offset
   816 000003C5 740F                        je  fix_locoff          ; yes
   817                                  
   818                                  ; first fixup is base or pointer
   819 000003C7 80FB03                      cmp bl,3                ; see if pointer
   820 000003CA 7412                        je  fix_15              ; ignore pointers, can't be split across fixupp records
   821                                  
   822                                  ; first fixup is base
   823 000003CC 8B1E[0000]                  mov bx,[target_index]
   824 000003D0 891E[1A00]                  mov [first_curr_segnum],bx    ; save index info
   825 000003D4 EB08                        jmp SHORT fix_15        ; bypass offset code
   826                                  
   827                                  ; first fixup is offset
   828                                  fix_locoff:
   829 000003D6 8B1E[0000]                  mov bx,[target_index]
   830 000003DA 891E[1600]                  mov [first_curr_offnum],bx    ; save index info
   831                                  
   832                                  fix_15:
   833 000003DE 268A1E0E00                  mov bl,[es:14]          ; get definition flag
   834 000003E3 80E303                      and bl,3                ; mask off extraneous bits
   835                                  
   836                                  ; Check if non-overlay class segment and overlaid public or unknown public.
   837 000003E6 833E[0600]00                cmp word [ovl_data_seg],0      ; see if nonoverlay class segment
   838 000003EB 756B                        jne fix_seg_ovl_class   ; no
   839 000003ED 2401                        and al,1                ; see if overlaid public
   840 000003EF 750A                        jne non_ovl_save        ; yes, save this reference
   841 000003F1 80FB02                      cmp bl,2                ; check if public or absolute
   842 000003F4 7205                        jb  non_ovl_save        ; no, save unknown reference
   843                                  
   844                                  ; reference to known nonoverlaid public
   845                                  nosave_ref:
   846 000003F6 8EC2                        mov es,dx               ; restore es -> i/o buffer
   847 000003F8 E95201                      jmp NEAR PTR next_fix   ; check next fixup
   848                                  
   849                                  ; save this reference to an overlaid or unknown public in a non-overlay class segment
   850                                  non_ovl_save:
   851 000003FB 8EC2                        mov es,dx               ; restore es -> i/o buffer
   852 000003FD 803E[0000]03                cmp byte [loc],3               ; see if pointer fixup
   853 00000402 7503                        jne non_ovl_chkref      ; no
   854 00000404 E9E200                      jmp NEAR PTR fix_overlaid   ; yes, save reference
   855                                  
   856                                  ; reference is either base or offset (loc == 2, 1, or 5)
   857                                  non_ovl_chkref:
   858 00000407 8B1E[0E00]                  mov bx,[segpart_owner]    ; get info to save
   859 0000040B A1[0000]                    mov ax,[target_index]
   860 0000040E 803E[0000]02                cmp byte [loc],2               ; see if base fixup
   861 00000413 741F                        je  non_ovl_base        ; yes
   862                                  
   863                                  ; offset fixup of indirect reference
   864 00000415 891E[1200]                  mov [off_extdef_segpart],bx   ; save segment partition info
   865 00000419 A3[0200]                    mov [off_extdef_number],ax    ; save index info
   866 0000041C 3B1E[1400]                  cmp bx,[seg_extdef_segpart]   ; check segment partition entries
   867 00000420 750C                        jne to_next_fix         ; no match, ignore
   868                                  
   869 00000422 3B06[2000]                  cmp ax,[first_prev_segnum]    ; see if offset matches first previous base fixup index
   870 00000426 7409                        je  to_set_off_flag     ; yes
   871                                  
   872 00000428 3B06[0400]                  cmp ax,[seg_extdef_number]    ; see if offset matches previous base fixup index
   873 0000042C 7403                        je  to_set_off_flag     ; yes
   874                                  
   875                                  to_next_fix:
   876 0000042E E91C01                      jmp NEAR PTR next_fix   ; no, ignore
   877                                  
   878                                  to_set_off_flag:
   879 00000431 E9B000                      jmp NEAR PTR set_off_flag   ; set offset is far flag, save reference
   880                                  
   881                                  ; base fixup of indirect reference
   882                                  non_ovl_base:
   883 00000434 891E[1400]                  mov [seg_extdef_segpart],bx   ; save segment partition info
   884 00000438 A3[0400]                    mov [seg_extdef_number],ax    ; save index info
   885 0000043B 3B1E[1200]                  cmp bx,[off_extdef_segpart]   ; check segment partition entries
   886 0000043F 7514                        jne to_next_fix2        ; no match, ignore
   887                                  
   888 00000441 3B06[1C00]                  cmp ax,[first_prev_offnum]    ; see if base matches first previous offset fixup index
   889 00000445 7406                        je  fix_chk_loc         ; yes
   890                                  
   891 00000447 3B06[0200]                  cmp ax,[off_extdef_number]    ; see if base matches previous offset fixup index
   892 0000044B 7508                        jne to_next_fix2        ; no, ignore
   893                                  
   894                                  fix_chk_loc:
   895 0000044D C606[0000]01                mov byte [loc],1               ; change base to offset so reference saved as far offset
   896 00000452 E98F00                      jmp NEAR PTR set_off_flag   ; set offset is far flag, save reference
   897                                  
   898                                  to_next_fix2:
   899 00000455 E9F500                      jmp NEAR PTR next_fix
   900                                  
   901                                  fix_seg_ovl_class:
   902 00000458 8EC2                        mov es,dx               ; es -> i/o buffer
   903 0000045A 88C4                        mov ah,al               ; save bit flags
   904 0000045C 2401                        and al,1                ; get overlaid bit
   905 0000045E 7518                        jne is_ovl_save         ; overlaid public, process
   906                                  
   907                                  ; check if public is overlay class and current segment is overlaid
   908                                  ; (have to track overlays calling the root)
   909 00000460 803E[0000]00                cmp byte [data_seg_overlaid],0 ; see if segment is overlaid
   910 00000465 740C                        je  fix_16              ; no, check publics to see if resolved or not
   911                                  
   912                                  ; check if nonvector root calls flag is set, if so don't track overlays
   913                                  ; calling the root
   914 00000467 803E[0000]00                cmp byte [nonovl_rvect],0      ; see if nonvectored root call
   915 0000046C 7505                        jne fix_16              ; yes, bypass check of overlay class bit
   916                                  
   917 0000046E 80E408                      and ah,8                ; get overlay class bit
   918 00000471 7505                        jne is_ovl_save         ; overlay class public called from overlay, save it
   919                                  
   920                                  ; bl holds definition flag value
   921                                  fix_16:
   922 00000473 80FB02                      cmp bl,2                ; check if resolved to public or absolute
   923 00000476 73DD                        jae to_next_fix2        ; resolved public, not overlaid
   924                                  
   925                                  ; unresolved public, could be overlaid, save it and check it after pass 1
   926                                  
   927                                  is_ovl_save:
   928 00000478 803E[0000]03                cmp byte [loc],3               ; see if pointer fixup
   929 0000047D 746A                        je  fix_overlaid        ; yes
   930 0000047F 8B1E[0E00]                  mov bx,[segpart_owner]    ; get info to save
   931 00000483 A1[0000]                    mov ax,[target_index]
   932 00000486 803E[0000]02                cmp byte [loc],2               ; see if base fixup
   933 0000048B 753E                        jne is_ovl_off          ; no, offset
   934                                  
   935                                  ; base fixup of direct reference
   936 0000048D 891E[1400]                  mov [seg_extdef_segpart],bx   ; save segment partition info
   937 00000491 A3[0400]                    mov [seg_extdef_number],ax    ; save index info
   938 00000494 3B1E[1200]                  cmp bx,[off_extdef_segpart]   ; check segment partition entries
   939 00000498 75BB                        jne to_next_fix2        ; no match, ignore
   940                                  
   941 0000049A 8B1E[1E00]                  mov bx,[first_prev_offptr]    ; init bx -> first previous offset entry
   942 0000049E 3B06[1C00]                  cmp ax,[first_prev_offnum]    ; see if base matches first previous offset fixup index
   943 000004A2 740A                        je  fix_near_far        ; yes
   944                                  
   945 000004A4 3B06[0200]                  cmp ax,[off_extdef_number]    ; see if base matches previous offset fixup index
   946 000004A8 75AB                        jne to_next_fix2        ; no, ignore
   947                                  
   948 000004AA 8B1E[1000]                  mov bx,[off_extdef_ptr]   ; bx -> previous offset entry
   949                                  
   950                                  ; base fixup matches previous offset fixup, update near offset to far offset
   951                                  fix_near_far:
   952 000004AE 8A4701                      mov al,[bx+1]           ; get high byte holds flag bits
   953 000004B1 A840                        test    al,40h          ; see if near bit set
   954 000004B3 74A0                        je  to_next_fix2        ; no, change nothing
   955 000004B5 24BF                        and al,0bfh             ; reset near bit
   956                                  
   957 000004B7 A880                        test    al,80h          ; see if high bit already set
   958 000004B9 7506                        jne is_ovl_2            ; yes
   959 000004BB 0C80                        or  al,80h              ; set far bit
   960 000004BD FF06[0A00]                  inc word [curseg_farovlpub_count]  ; bump count of far references
   961                                  
   962                                  is_ovl_2:
   963 000004C1 884701                      mov [bx+1],al           ; update high byte with new flag bits
   964 000004C4 FF0E[0800]                  dec word [curseg_nearovlpub_count] ; drop count of near references
   965 000004C8 E98200                      jmp NEAR PTR next_fix   ; continue
   966                                  
   967                                  ; offset fixup of direct reference
   968                                  is_ovl_off:
   969 000004CB 891E[1200]                  mov [off_extdef_segpart],bx   ; save segment partition info
   970 000004CF A3[0200]                    mov [off_extdef_number],ax    ; save index info
   971 000004D2 3B1E[1400]                  cmp bx,[seg_extdef_segpart]   ; check segment partition entries
   972 000004D6 7511                        jne fix_overlaid        ; no, assume near call
   973                                  
   974 000004D8 3B06[2000]                  cmp ax,[first_prev_segnum]    ; see if offset matches previous base fixup index
   975 000004DC 7406                        je  set_off_flag        ; yes
   976                                  
   977 000004DE 3B06[0400]                  cmp ax,[seg_extdef_number]    ; see if offset matches previous base fixup index
   978 000004E2 7505                        jne fix_overlaid        ; no, assume near call
   979                                  
   980                                  ; set the offset is far flag so it is treated as far reference
   981                                  set_off_flag:
   982 000004E4 C606[0200]01                mov byte [off_to_far_flag],1
   983                                  
   984                                  ; put symbol in overlaid publics array
   985                                  ; first check if need to flush pre-existing segment's publics to table
   986                                  fix_overlaid:
   987 000004E9 A1[0C00]                    mov ax,[ovlpub_array_seg] ; get the array segment
   988 000004EC 3B06[0600]                  cmp ax,[ovl_data_seg]     ; see if matches the overlaid segment partition entry
   989 000004F0 740B                        je  fix_markpub         ; yes
   990 000004F2 83F8FF                      cmp ax,-1               ; see if array segment has been set (previous overlaid publics)
   991 000004F5 7403                        je  fix_17              ; no bypass flush of old publics to table
   992                                  
   993                                  fix_flush:
   994 000004F7 E85C00                      call    flush_publics   ; flush previous segment partition publics to table
   995                                  
   996                                  fix_17:
   997 000004FA E82F01                      call    init_pubarray   ; reset public array to zeros, reset variables
   998                                  
   999                                  ; di still holds offset into array (extdef index, relative 0)
  1000                                  fix_markpub:
  1001 000004FD 81C7[0000]                  add di,OFFSET ovlpub_array wrt DGROUP   ; di -> proper element in array of overlaid publics
  1002 00000501 8B1D                        mov bx,[di]             ; get pre-existing element
  1003 00000503 80E7C0                      and bh,0c0h             ; only keep near and far flag bits
  1004 00000506 A1[0000]                    mov ax,[target_index]     ; get index of public declaration
  1005 00000509 803E[0200]00                cmp byte [off_to_far_flag],0   ; see if offset is far flag set
  1006 0000050E 7509                        jne fix_faroff          ; yes, all references are far, offset or pointer
  1007 00000510 803E[0000]03                cmp byte [loc],3               ; see if near or far use of extdef
  1008 00000515 7516                        jne fix_near            ; near
  1009 00000517 EB04                        jmp SHORT fix_far
  1010                                  
  1011                                  ; offset promoted to far call due to base match
  1012                                  fix_faroff:
  1013 00000519 893E[1000]                  mov [off_extdef_ptr],di   ; save pointer to near value in case of later base match
  1014                                  
  1015                                  fix_far:
  1016 0000051D F6C780                      test    bh,80h          ; get previous far bit value
  1017 00000520 752B                        jne next_fix            ; already existent far setting, don't update array
  1018 00000522 80CC80                      or  ah,80h              ; set high bit to indicate far call
  1019 00000525 08FC                        or  ah,bh               ; merge in near bit if previously set
  1020 00000527 FF06[0A00]                  inc word [curseg_farovlpub_count]  ; bump count of far overlaid publics
  1021 0000052B EB1E                        jmp SHORT fix_18        ; bypass near bit set
  1022                                  
  1023                                  ; near use of extdef
  1024                                  fix_near:
  1025 0000052D 893E[1000]                  mov [off_extdef_ptr],di   ; save pointer to near value in case later promotion to far
  1026                                  
  1027 00000531 8B16[1800]                  mov dx,[first_curr_offptr]    ; get first current pointer to near value
  1028 00000535 09D2                        or  dx,dx               ; see if previous pointer
  1029 00000537 7504                        jne fix_near2           ; yes
  1030 00000539 893E[1800]                  mov [first_curr_offptr],di    ; save new pointer value
  1031                                  
  1032                                  fix_near2:
  1033 0000053D F6C740                      test    bh,40h          ; get previous near bit value
  1034 00000540 750B                        jne next_fix            ; already existent near setting, don't update array
  1035 00000542 80CC40                      or  ah,40h              ; set bit 14 to indicate near call
  1036 00000545 08FC                        or  ah,bh               ; merge in far bit if previously set
  1037 00000547 FF06[0800]                  inc word [curseg_nearovlpub_count] ; bump count of near overlaid publics
  1038                                  
  1039                                  fix_18:
  1040 0000054B 8905                        mov [di],ax             ; put overlaid public in array
  1041                                  
  1042                                  next_fix:
  1043 0000054D 83F901                      cmp cx,1                ; check if at checksum byte
  1044 00000550 7603                        jbe fix_ret             ; yes, done
  1045 00000552 E928FD                      jmp NEAR PTR fix_2      ; no, check next fixup
  1046                                  
  1047                                  fix_ret:
  1048 00000555 C3                          ret
  1049                                  proc1_fixupp    ENDP
  1050                                  
  1051                                  ;*****************************
  1052                                  ;* FLUSH_PUBLICS             *
  1053                                  ;*****************************
  1054                                  
  1055                                  ; flush segment partition entry's overlaid publics to table
  1056                                  ; destroys ax,bx,dx
  1057                                  
  1058                                  flush_publics   PROC
  1059 00000556 06                          push    es              ; save critical register
  1060 00000557 56                          push    si
  1061 00000558 51                          push    cx
  1062 00000559 A1[0000]                    mov ax,[alloc_ovlpubblk_ptr]  ; get pointer to last allocated block
  1063 0000055C 09C0                        or  ax,ax
  1064 0000055E 751B                        jne flush_2             ; at least one block allocated
  1065                                  
  1066 00000560 BB4000                      mov bx,OVLPUB_BLK_SIZE  ; get size of overlaid public declarations block to allocate
  1067 00000563 E8(0000)                    call    alloc_memory    ; get memory for block allocation
  1068 00000566 8EC0                        mov es,ax               ; es -> block
  1069 00000568 26C70600000000              mov WORD PTR [es:0],0   ; zero next block pointer
  1070 0000056F C706[0000]0200              mov word [ovlpubblk_pos],2     ; init block pointer position
  1071 00000575 A3[0000]                    mov [alloc_ovlpubblk_ptr],ax  ; update last allocated block pointer
  1072 00000578 A3[0000]                    mov [first_ovlpubblk_ptr],ax  ; update first allocate block pointer
  1073                                  
  1074                                  flush_2:
  1075 0000057B 8EC0                        mov es,ax               ; es -> block
  1076 0000057D 8B1E[0000]                  mov bx,[ovlpubblk_pos]    ; bx offsets into block
  1077                                  
  1078                                  ; first write segment partition flag and entry value
  1079 00000581 81FBF703                    cmp bx,OVLPUB_BLK_BYSIZE-9  ; see if at end of block (no room for segment partition entry info)
  1080 00000585 7203                        jb  flush_3             ; no
  1081                                  
  1082 00000587 E87F00                      call    new_ovlpub_blk  ; make new overlaid public block
  1083                                  
  1084                                  flush_3:
  1085 0000058A B001                        mov al,1
  1086 0000058C 833E[0C00]00                cmp word [ovlpub_array_seg],0  ; see if nonoverlay class segment
  1087 00000591 7502                        jne flush_3a            ; no
  1088 00000593 FEC0                        inc al                  ; yes, set flag to value of 2
  1089                                  
  1090                                  flush_3a:
  1091 00000595 268807                      mov BYTE PTR [es:bx],al  ; set segment partition entry flag
  1092 00000598 43                          inc bx                   ; bump offset
  1093                                  
  1094                                  ; now write segment partition entry value
  1095                                  flush_4:
  1096 00000599 A1[0C00]                    mov ax,[ovlpub_array_seg]
  1097 0000059C 268907                      mov WORD PTR [es:bx],ax
  1098 0000059F A1[0800]                    mov ax,[curseg_nearovlpub_count]  ; get near overlaid publics count
  1099 000005A2 26894702                    mov WORD PTR [es:bx+2],ax   ; save it
  1100 000005A6 89C1                        mov cx,ax
  1101 000005A8 A1[0A00]                    mov ax,[curseg_farovlpub_count]   ; get far overlaid publics count
  1102 000005AB 26894704                    mov WORD PTR [es:bx+4],ax   ; save it
  1103 000005AF 01C1                        add cx,ax               ; cx holds count of near and far overlaid publics
  1104 000005B1 31C0                        xor ax,ax
  1105 000005B3 26894706                    mov WORD PTR [es:bx+6],ax   ; init total used references count
  1106 000005B7 83C308                      add bx,8                ; adjust offset past info bytes
  1107                                  
  1108                                  ; write public entries
  1109 000005BA BE[0000]                    mov si,OFFSET ovlpub_array wrt DGROUP   ; si offsets into array
  1110                                  
  1111                                  flush_loop:
  1112 000005BD 8B04                        mov ax,[si]             ; get element
  1113 000005BF 09C0                        or  ax,ax               ; see if nonzero
  1114 000005C1 7437                        je  flush_next          ; no, get next element
  1115 000005C3 88E6                        mov dh,ah
  1116 000005C5 25FF3F                      and ax,03fffh           ; mask off near and far flag bits
  1117 000005C8 80E6C0                      and dh,0c0h             ; only keep near and far flag bits
  1118 000005CB F6C680                      test    dh,80h          ; see if far bit set
  1119 000005CE 7401                        je  flush_near          ; no
  1120 000005D0 49                          dec cx                  ; yes, drop count of publics to save
  1121                                  
  1122                                  flush_near:
  1123 000005D1 F6C640                      test    dh,40h          ; see if near bit set
  1124 000005D4 7401                        je  flush_5             ; no
  1125 000005D6 49                          dec cx                  ; yes, drop count of publics to save
  1126                                  
  1127                                  flush_5:
  1128 000005D7 81FBFD03                    cmp bx,OVLPUB_BLK_BYSIZE-3  ; see if at end of block, no room for public info
  1129 000005DB 7205                        jb  flush_6             ; no
  1130                                  
  1131 000005DD 50                          push    ax              ; save index in ax
  1132 000005DE E82800                      call    new_ovlpub_blk  ; make new overlaid public block
  1133 000005E1 58                          pop ax                  ; restore index in ax
  1134                                  
  1135                                  flush_6:
  1136 000005E2 268837                      mov [es:bx],dh          ; set flag bits byte
  1137                                  
  1138                                  ; look up public declaration segment entry from index in ax
  1139 000005E5 48                          dec ax                  ; make ax relative zero offset
  1140 000005E6 D1E0                        shl ax,1                ; convert ax to word offset
  1141 000005E8 89DA                        mov dx,bx               ; save bx value
  1142 000005EA BB[0000]                    mov bx,OFFSET ext_defent_indptr wrt DGROUP  ; set bx to base of pubdef declarations entry array
  1143 000005ED 01C3                        add bx,ax               ; bx -> array element holding pubdef declarations entry address
  1144 000005EF 8B07                        mov ax,[bx]             ; ax -> pubdef declarations entry of referenced EXTDEF in FIXUPP record
  1145 000005F1 89D3                        mov bx,dx               ; restore bx value
  1146 000005F3 26894701                    mov [es:bx+1],ax        ; keep public declaration entry segment
  1147 000005F7 83C303                      add bx,3                ; bump to next free slot in table
  1148                                  
  1149                                  flush_next:
  1150 000005FA E305                        jcxz    flush_ret       ; no more overlaid public declaration entries to save 
  1151 000005FC 83C602                      add si,2                ; bump to next position in array
  1152 000005FF EBBC                        jmp SHORT flush_loop    ; loop back for more
  1153                                  
  1154                                  flush_ret:
  1155 00000601 891E[0000]                  mov [ovlpubblk_pos],bx    ; update offset into block
  1156 00000605 59                          pop cx                  ; restore critical register
  1157 00000606 5E                          pop si
  1158 00000607 07                          pop es
  1159 00000608 C3                          ret
  1160                                  flush_publics   ENDP
  1161                                  
  1162                                  ;*****************************
  1163                                  ;* NEW_OVLPUB_BLK            *
  1164                                  ;*****************************
  1165                                  
  1166                                  ; create new overlaid public block
  1167                                  ; inits bx,ovlpubblk_pos variable
  1168                                  ; returns segment of new block in es
  1169                                  ; destroys ax,bx,es
  1170                                  
  1171                                  new_ovlpub_blk  PROC
  1172 00000609 A1[0000]                    mov ax,[alloc_ovlpubblk_ptr]  ; get old last allocated block
  1173 0000060C 50                          push    ax              ; save on stack
  1174 0000060D BB4000                      mov bx,OVLPUB_BLK_SIZE  ; get size of overlaid public declarations block to allocate
  1175 00000610 E8(0000)                    call    alloc_memory    ; get memory for block allocation
  1176 00000613 07                          pop es                  ; es -> old block
  1177 00000614 26A30000                    mov [es:0],ax           ; save -> new block in old block
  1178 00000618 A3[0000]                    mov [alloc_ovlpubblk_ptr],ax  ; update last allocated block variable
  1179 0000061B 8EC0                        mov es,ax               ; es -> new block
  1180 0000061D 31C0                        xor ax,ax
  1181 0000061F 26A30000                    mov WORD PTR [es:0],ax  ; zero next block pointer
  1182 00000623 B80200                      mov ax,2
  1183 00000626 A3[0000]                    mov [ovlpubblk_pos],ax
  1184 00000629 89C3                        mov bx,ax
  1185 0000062B C3                          ret
  1186                                  new_ovlpub_blk  ENDP
  1187                                  
  1188                                  ;*****************************
  1189                                  ;* INIT_PUBARRAY             *
  1190                                  ;*****************************
  1191                                  
  1192                                  ; zero all entries in the overlaid public array
  1193                                  ; initialize other array variables
  1194                                  ; destroys ax,bx
  1195                                  
  1196                                  init_pubarray   PROC
  1197 0000062C 06                          push    es              ; save critical register
  1198 0000062D 51                          push    cx
  1199 0000062E 57                          push    di
  1200                                  
  1201                                  ; zero the array
  1202 0000062F 8CD8                        mov ax,ds
  1203 00000631 8EC0                        mov es,ax
  1204 00000633 BF[0000]                    mov di,OFFSET ovlpub_array wrt DGROUP   ; es:di -> array to zero
  1205 00000636 B90002                      mov cx,OVLPUB_BLK_BYSIZE/2  ; get size of block in words
  1206 00000639 31C0                        xor ax,ax
  1207 0000063B F3AB                        rep stosw               ; zero it out
  1208                                  
  1209 0000063D A3[0800]                    mov [curseg_nearovlpub_count],ax  ; init the count of near and far overlaid publics
  1210 00000640 A3[0A00]                    mov [curseg_farovlpub_count],ax
  1211 00000643 A1[0600]                    mov ax,[ovl_data_seg]     ; get this segment partition entry
  1212 00000646 A3[0C00]                    mov [ovlpub_array_seg],ax ; set it as owning segment of publics to put in overlaid array
  1213                                  
  1214 00000649 5F                          pop di                  ; restore critical register
  1215 0000064A 59                          pop cx
  1216 0000064B 07                          pop es
  1217 0000064C C3                          ret
  1218                                  init_pubarray   ENDP
  1219                                  
  1220                                  END
