     1                                  ;*********************************************************************
     2                                  ;*   MLPASS2A.ASM                                                    *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          05/10/93                                         *
     6                                  ;*   Model:         Small                                            *
     7                                  ;*   Version:       2.7                                              *
     8                                  ;*   Assembler:     MASM 5.0                                         *
     9                                  ;*   Environment:   MS-DOS 2.x+                                      *
    10                                  ;*                                                                   *
    11                                  ;*   linker pass 2 routines part A                                   *
    12                                  ;*                                                                   *
    13                                  ;*********************************************************************
    14                                  
    15                                  ;TITLE   WARPLINK mlpass2a
    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                                  PUBLIC  pass2_obj_proc
    35                                  
    36                                  ;*****************************
    37                                  ;* Data begins               *
    38                                  ;*****************************
    39                                  
    40                                  .DATA
    41                                  
    42                                  ;*****************************
    43                                  ;* External declarations     *
    44                                  ;*****************************
    45                                  
    46                                  ; variables
    47                                  EXTRN   parse_complete:BYTE,filename:BYTE,libobj_flag:BYTE
    48                                  EXTRN   ovl_entry_id:WORD,ovl_code_count:WORD
    49                                  EXTRN	new_ledata_offset:WORD
    50                                  EXTRN	is_local:BYTE
    51                                  EXTRN	ignore_fixupp_flag:BYTE
    52                                  
    53                                  ; initialized local variables
    54                                  
    55                                  .DATA?
    56                                  ; uninitialized local variables
    57                                  
    58                                  ;*****************************
    59                                  ;* Code begins               *
    60                                  ;*****************************
    61                                  
    62                                  .CODE
    63                                  
    64                                  ;*****************************
    65                                  ;* External declarations     *
    66                                  ;*****************************
    67                                  
    68                                  ; procedures
    69                                  EXTRN   link_error:NEAR,dos_error:NEAR,load_file:NEAR,get_name:NEAR
    70                                  EXTRN   proc2_lnames:NEAR,proc2_extdef:NEAR,proc2_segdef:NEAR
    71                                  EXTRN   proc2_grpdef:NEAR,proc2_fixupp:NEAR,proc2_modend:NEAR
    72                                  EXTRN   proc2_data:NEAR
    73                                  ;*** EXTRN   proc_locals:NEAR,zero_local_blocks:NEAR
    74                                  EXTRN	pass2_clipcheck:NEAR
    75                                  
    76                                  ;*****************************
    77                                  ;* PASS2_OBJ_PROC            *
    78                                  ;*****************************
    79                                  
    80                                  ; parse and process records in object modules
    81                                  ; all registers used or destroyed
    82                                  
    83                                  pass2_obj_proc  PROC
    84 00000000 E8(0000)                	call	pass2_clipcheck	; see if Clipper module that is compressed
    85                                  
    86 00000003 31F6                        xor si,si               ; si points into buffer for parsed chars
    87 00000005 89F0                        mov ax,si
    88 00000007 A2[0000]                    mov [libobj_flag],al
    89 0000000A A1[0000]                    mov ax,[buffer_tail]      ; get buffer_tail variable in register for quick compares
    90 0000000D 89C5                        mov bp,ax               ; bp holds variable value
    91                                  
    92                                  ; entry point to process next module if more than one in specified OBJ
    93                                  p2_proc_next:
    94 0000000F 31C0                        xor ax,ax
    95 00000011 A2[0000]                    mov [parse_complete],al   ; init flag indicating record parsing is complete for object module
    96 00000014 A2[0000]                	mov	[ignore_fixupp_flag],al
    97 00000017 A3[0000]                    mov [current_lnames],ax   ; init count of current record types
    98 0000001A A3[0000]                    mov [current_extdef],ax
    99 0000001D A3[0000]                    mov [current_segdef],ax
   100 00000020 A3[0000]                    mov [current_grpdef],ax
   101 00000023 A3[0000]                	mov	[new_ledata_offset],ax	; init LEDATA data offset after compression
   102 00000026 A2[0000]                    mov [seg_ovlclass],al     ; init overlay class segment in module flag
   103 00000029 A1[0000]                    mov ax,[ovl_code_count]
   104 0000002C A3[0000]                    mov [ovl_entry_id],ax     ; save ovl_code_count entry value
   105                                  ;***    call    zero_local_blocks   ; zero any pre-existing local blocks (don't carry locals to next module)
   106                                  
   107                                  p2_proc_loop:
   108 0000002F 8936[0000]                  mov [read_buff_ptr],si    ; keep beginning of object record
   109 00000033 A1[0000]                    mov ax,[buffer_base]      ; get i/o buffer segment
   110 00000036 8EC0                        mov es,ax               ; es -> i/o buffer
   111 00000038 268A04                      mov al,[es:si]          ; get record type
   112                                  
   113                                  pop_2:
   114 0000003B 46                          inc si                  ; bump si past record type
   115 0000003C 39EE                        cmp si,bp               ; check boundary conditions
   116 0000003E 7203                        jb  pop_2a              ; okay
   117 00000040 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   118                                  pop_2a:
   119 00000043 268A0C                      mov cl,[es:si]          ; get record length low byte
   120 00000046 46                          inc si
   121 00000047 39EE                        cmp si,bp               ; check boundary conditions
   122 00000049 7203                        jb  pop_2c              ; okay
   123 0000004B E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   124                                  
   125                                  pop_2c:
   126 0000004E 268A2C                      mov ch,[es:si]          ; get record length high byte
   127 00000051 46                          inc si                  ; bump si past length word
   128 00000052 39EE                        cmp si,bp               ; check boundary conditions
   129 00000054 7203                        jb  pop_2e              ; okay
   130 00000056 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   131                                  
   132                                  pop_2e:
   133                                  ; check that record doesn't exceed file length
   134 00000059 803E[0000]00                cmp byte [eof_flag],0          ; see if end of file encountered
   135 0000005E 7406                        je  len_chk             ; nope
   136 00000060 89CA                        mov dx,cx               ; get record length
   137 00000062 01F2                        add dx,si               ; add in current position
   138 00000064 7212                        jc  unexpected_eof      ; overflow, fatal error
   139                                  
   140                                  len_chk:
   141 00000066 83F901                      cmp cx,1                ; see if null record
   142 00000069 7644                        jbe to_update_pos       ; yes, ignore it
   143                                  
   144                                  pop_2f:
   145 0000006B 3C96                        cmp al,LNAMES           ; is record a LNAMES record
   146 0000006D 7512                        jne pop_3
   147 0000006F E82301                      call    data_process    ; process any previous LEDATA or LIDATA record
   148 00000072 E8(0000)                    call    proc2_lnames    ; process the record
   149 00000075 E9E100                      jmp NEAR PTR parse_chk
   150                                  
   151                                  unexpected_eof:
   152 00000078 BA[0000]                    mov dx,OFFSET filename wrt DGROUP
   153 0000007B B80A00                      mov ax,UNEXPECT_EOF_ERR ; unexpected end of file
   154 0000007E E9(0000)                    jmp NEAR PTR link_error ; transfer control to error handler
   155                                  
   156                                  pop_3:
   157 00000081 3C8C                        cmp al,EXTDEF           ; is it a EXTDEF record
   158 00000083 750B                        jne pop_cextdef
   159                                  pop_extdef:
   160 00000085 50                          push    ax              ; save al record type
   161 00000086 E80C01                      call    data_process    ; process any previous LEDATA or LIDATA record
   162 00000089 58                          pop ax                  ; restore al record type
   163 0000008A E8(0000)                    call    proc2_extdef    ; process the record
   164 0000008D E9B000                      jmp NEAR PTR update_pos
   165                                  
   166                                  pop_cextdef:
   167 00000090 3CBC                        cmp al,CEXTDEF			; is it a CEXTDEF record
   168 00000092 74F1                        je pop_extdef			; yes
   169                                  
   170 00000094 3CB0                        cmp al,COMDEF           ; check if a COMDEF record
   171 00000096 74ED                        je  pop_extdef          ; COMDEF behaves as an EXTDEF record on second pass
   172                                  
   173 00000098 3C98                        cmp al,SEGDEF           ; is it an SEGDEF record
   174 0000009A 7509                        jne pop_5
   175 0000009C E8F600                      call    data_process    ; process any previous LEDATA or LIDATA record
   176 0000009F E8(0000)                    call    proc2_segdef    ; process the record
   177 000000A2 E9B400                      jmp NEAR PTR parse_chk
   178                                  pop_5:
   179 000000A5 3C9A                        cmp al,GRPDEF           ; is it a GRPDEF record
   180 000000A7 7509                        jne pop_6
   181 000000A9 E8E900                      call    data_process    ; process any previous LEDATA or LIDATA record
   182 000000AC E8(0000)                    call    proc2_grpdef    ; process the record
   183                                  
   184                                  to_update_pos:
   185 000000AF E98E00                      jmp NEAR PTR update_pos
   186                                  pop_6:
   187 000000B2 3C9C                        cmp al,FIXUPP           ; is it a FIXUPP record
   188 000000B4 7506                        jne pop_7
   189 000000B6 E8(0000)                    call    proc2_fixupp    ; process the record
   190 000000B9 E98400                      jmp NEAR PTR update_pos
   191                                  
   192                                  pop_7:
   193 000000BC 3CA0                        cmp al,LEDATA           ; is it a LEDATA record
   194 000000BE 7511                        jne pop_8
   195 000000C0 803E[0000]00                cmp byte [prev_flag],0         ; yes, see if prevous data record pending
   196 000000C5 7403                        je  pop_7a              ; no
   197 000000C7 E8CB00                      call    data_process    ; process the previous data record
   198                                  pop_7a:
   199 000000CA C606[0000]01                mov byte [prev_flag],1         ; flag LEDATA record on hold
   200 000000CF EB13                        jmp SHORT pop_data      ; jump to code shared with LIDATA record
   201                                  pop_8:
   202 000000D1 3CA2                        cmp al,LIDATA           ; is it a LIDATA record
   203 000000D3 7525                        jne pop_9
   204 000000D5 803E[0000]00                cmp byte [prev_flag],0         ; yes, see if prevous data record pending
   205 000000DA 7403                        je  pop_8a              ; no
   206 000000DC E8B600                      call    data_process    ; process the previous data record
   207                                  pop_8a:
   208 000000DF C606[0000]02                mov byte [prev_flag],2         ; flag LIDATA record on hold
   209                                  pop_data:
   210 000000E4 8936[0000]                  mov [prev_read_ptr],si    ; save pointer to record in file buffer
   211 000000E8 890E[0000]                  mov [prev_rec_len],cx     ; save length of record
   212 000000EC A1[0000]                    mov ax,WORD PTR [file_pos_adj]    ; get file offset adjustment high word
   213 000000EF A3[0000]                    mov WORD PTR [prev_pos_adj],ax    ; save it
   214 000000F2 A1[0200]                    mov ax,WORD PTR [file_pos_adj+2]  ; get file offset adjustment low word
   215 000000F5 A3[0200]                    mov WORD PTR [prev_pos_adj+2],ax  ; save it
   216 000000F8 EB46                        jmp SHORT update_pos
   217                                  
   218                                  pop_9:
   219 000000FA 3C8A                        cmp al,MODEND           ; is it a MODEND record
   220 000000FC 750B                        jne pop_10              ; no
   221 000000FE A2[0000]                    mov [parse_complete],al   ; al is known nonzero value, put it in parse_complete flag
   222 00000101 E89100                      call    data_process    ; process any previous LEDATA or LIDATA record
   223 00000104 E8(0000)                    call    proc2_modend    ; process the record
   224 00000107 EB37                        jmp SHORT update_pos
   225                                  
   226                                  pop_10:
   227 00000109 3C80                        cmp al,THEADR           ; is it a THEADR record
   228 0000010B 7505                        jne pop_mslhed          ; no
   229 0000010D E87900                      call    proc2_theadr    ; process the record
   230 00000110 EB2E                        jmp SHORT update_pos
   231                                  
   232                                  pop_mslhed:
   233 00000112 3CF0                        cmp al,MSLHED           ; make library header records valid
   234 00000114 7505                        jne pop_11
   235 00000116 A2[0000]                    mov [libobj_flag],al      ; set library as object flag
   236 00000119 EB25                        jmp SHORT update_pos
   237                                  
   238                                  pop_11:
   239 0000011B 3C82                        cmp al,LHEADR           ; is it a LHEADR record
   240 0000011D 7505                        jne pop_12              ; no
   241 0000011F E86700                      call    proc2_theadr    ; LHEADR processes the sames as THEADR
   242 00000122 EB1C                        jmp SHORT update_pos
   243                                  
   244                                  ; local symbol processing
   245                                  pop_12:
   246 00000124 3CB4                        cmp al,LEXTDEF          ; check if LEXTDEF record
   247 00000126 7503                        jne pop_12b
   248                                  to_pop_extdef:
   249 00000128 E95AFF                  	jmp	NEAR PTR pop_extdef
   250                                  
   251                                  pop_12b:
   252 0000012B 3CB8                        cmp al,LCOMDEF          ; check if a LCOMDEF record
   253 0000012D 74F9                    	je	to_pop_extdef		; yes, process as EXTDEF
   254                                  
   255 0000012F 3CA1                        cmp al,LEDATA32			; check if a LEDATA32 record
   256 00000131 750A                    	jne	pop_ignore			; no
   257 00000133 E85F00                      call    data_process    ; process any previous LEDATA or LIDATA record
   258 00000136 C606[0000]01            	mov	byte [ignore_fixupp_flag],1	; yes, flag ignore following FIXUPP
   259 0000013B EB03                    	jmp	SHORT update_pos
   260                                  
   261                                  ; remaining record types ignored, but check for previous L?DATA record to process
   262                                  pop_ignore:
   263 0000013D E85500                      call    data_process    ; process any previous LEDATA or LIDATA record
   264                                  
   265                                  update_pos:                 ; update si to point past record
   266 00000140 89F2                        mov dx,si               ; save current position prior to update
   267 00000142 01CE                        add si,cx               ; scan past remaining bytes
   268 00000144 730F                        jnc pop_14              ; no overflow
   269                                  
   270                                  pop_13:
   271 00000146 89D6                        mov si,dx               ; restore si to current position
   272 00000148 89E8                        mov ax,bp               ; get overflow point
   273 0000014A 29F0                        sub ax,si               ; get difference from current position to overflow
   274 0000014C 89EE                        mov si,bp               ; put si at overflow point
   275 0000014E 29C1                        sub cx,ax               ; update cx to account for changed si position
   276 00000150 E8(0000)                    call    load_file       ; load next portion of file into buffer, at end position
   277 00000153 EBEB                        jmp SHORT update_pos    ; loop back for next attempt
   278                                  
   279                                  pop_14:
   280 00000155 39EE                        cmp si,bp               ; check boundary conditions
   281 00000157 73ED                        jae pop_13              ; out of bounds
   282                                  
   283                                  parse_chk:
   284 00000159 A0[0000]                    mov al,[parse_complete]
   285 0000015C 08C0                        or  al,al               ; see if parsing should continue
   286 0000015E 7503                        jne pop_done            ; parsing complete for this module
   287 00000160 E9CCFE                      jmp NEAR PTR p2_proc_loop   ; loop for next record
   288                                  
   289                                  pop_done:
   290 00000163 803E[0000]00                cmp byte [is_inlib],0          ; see if processing library
   291 00000168 751B                        jne pop_ret             ; yes
   292                                  
   293 0000016A 803E[0000]00                cmp byte [libobj_flag],0       ; see if library treated as object module
   294 0000016F 7414                        je  pop_ret             ; no
   295                                  
   296 00000171 268A04                      mov al,[es:si]          ; get next record type
   297 00000174 3C80                        cmp al,THEADR           ; see if start of new object module
   298 00000176 740E                        je  pop_more            ; yes
   299 00000178 3C82                        cmp al,LHEADR           ; see if start of new object module
   300 0000017A 740A                        je  pop_more            ; yes
   301                                  
   302 0000017C 08C0                        or  al,al               ; see of zero (padding)
   303 0000017E 7505                        jne pop_ret             ; no
   304 00000180 B90100                      mov cx,1                ; setup to eat one byte
   305 00000183 EBBB                        jmp SHORT update_pos    ; loop back
   306                                  
   307                                  pop_ret:
   308 00000185 C3                          ret
   309                                  
   310                                  pop_more:
   311 00000186 E986FE                      jmp NEAR PTR p2_proc_next   ; get next module in file
   312                                  
   313                                  pass2_obj_proc  ENDP
   314                                  
   315                                  ;*****************************
   316                                  ;* PROC2_THEADR              *
   317                                  ;*****************************
   318                                  
   319                                  ; process THEADR record
   320                                  ; upon entry cx=record length,bp=buffer_end,al=record type
   321                                  ; si -> first byte of record past record length
   322                                  ; destroys ax
   323                                  ; updates si
   324                                  
   325                                  proc2_theadr    PROC
   326 00000189 BF[0000]                    mov di,OFFSET tmod_name wrt DGROUP  ; di -> field to place name
   327 0000018C C606[0000]00            	mov	byte [is_local],0			; flag not a local for get_name
   328 00000191 E8(0000)                    call    get_name        ; get and save T-module name
   329 00000194 C3                          ret                     ; all done
   330                                  proc2_theadr    ENDP
   331                                  
   332                                  ;*****************************
   333                                  ;* DATA_PROCESS              *
   334                                  ;*****************************
   335                                  
   336                                  ; determine if previous records was LEDATA or LIDATA record, and process if so
   337                                  ; destroys ax,bx,dx,di
   338                                  
   339                                  data_process    PROC
   340 00000195 803E[0000]00                cmp byte [prev_flag],0         ; check if previous record was L?DATA
   341 0000019A 7408                        je  dp_ret              ; no
   342 0000019C E8(0000)                    call    proc2_data      ; process previous L?DATA record
   343 0000019F C606[0000]00                mov byte [prev_flag],0         ; reset previous record flag
   344                                  
   345                                  dp_ret:
   346 000001A4 C3                          ret
   347                                  data_process    ENDP
   348                                  
   349                                  END
