     1                                  ;*********************************************************************
     2                                  ;*   MLPASS1.ASM                                                     *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          09/28/92                                         *
     6                                  ;*   Model:         Small                                            *
     7                                  ;*   Version:       1.0                                              *
     8                                  ;*   Assembler:     MASM 5.0                                         *
     9                                  ;*   Environment:   MS-DOS 2.x+                                      *
    10                                  ;*                                                                   *
    11                                  ;*   linker pass 1 main driver                                       *
    12                                  ;*                                                                   *
    13                                  ;*********************************************************************
    14                                  
    15                                  ;TITLE   WARPLINK mlpass1
    16                                  ;PAGE    50,80
    17                                  
    18                                  ;.MODEL  SMALL
    19                                  
    20                                  ;*****************************
    21                                  ;* Include files             *
    22                                  ;*****************************
    23                                  
    24                                  [list -]
    28                                       
    29                                  ;*****************************
    30                                  ;* Public declarations       *
    31                                  ;*****************************
    32                                       
    33                                  PUBLIC  pass1,make_symbols
    34                                  
    35                                  ;*****************************
    36                                  ;* External declarations     *
    37                                  ;*****************************
    38                                  
    39                                  EXTRN   perform_pass:NEAR,get_pubdecl_entry:NEAR,add_pubdef_name:NEAR
    40                                  EXTRN   alloc_memory:NEAR,init_segdef_entry:NEAR
    41                                  
    42                                  %IFNDEF JUNIOR
    43                                  EXTRN   save_lib_name:NEAR,check_extension:NEAR
    44                                  %ENDIF
    45                                  
    46                                  ;*****************************
    47                                  ;* Data begins               *
    48                                  ;*****************************
    49                                       
    50                                  .DATA
    51                                  
    52                                  .DATA?
    53                                  
    54                                  ; uninitialized local variables
    55                                  
    56 00000000 ????                    nullcode_segdef DW  ?   ; segdef entry of null code first segment
    57                                  
    58                                  ;*****************************
    59                                  ;* External declarations     *
    60                                  ;*****************************
    61                                  
    62                                  ; variables
    63                                  EXTRN   smartmem_count:WORD
    64                                  
    65                                  ;*****************************
    66                                  ;* Constant data             *
    67                                  ;*****************************
    68                                  
    69                                  .CONST
    70                                  
    71                                  ; sumbols generated by use of DOSSEG switch
    72                                  EVEN
    73 00000000 5F454441544100          _edatatext  DB  '_EDATA',0
    74 00000007 00                      EVEN
    75 00000008 5F454E4400              _end    DB  '_END',0
    76 0000000D 00                      EVEN
    77 0000000E 5F656461746100          lc_edatatext  DB  '_edata',0
    78 00000015 00                      EVEN
    79 00000016 5F656E6400              lc_end    DB  '_end',0
    80                                  
    81 0000001B 24245F4F564C5F4D41-     ovlclass_text   DB  '$$_OVL_MANAGER',0  ; class name for overlaid public lookup table segment
    81 00000024 4E4147455200       
    82 0000002A 24245F4F564C5F4C4F-     ovlseg_text     DB  '$$_OVL_LOOKUP_TABLE',0 ; segment name for overlaid public lookup table segment
    82 00000033 4F4B55505F5441424C-
    82 0000003C 4500               
    83 0000003E 24245F4F564C5F494E-     ovlind_text     DB  '$$_OVL_IND_CALL_TABLE',0   ; segment name for indirect call vector segment
    83 00000047 445F43414C4C5F5441-
    83 00000050 424C4500           
    84 00000054 24245F4F564C5F5345-     ovlscall_text   DB  '$$_OVL_SEG_CALL_TABLE',0   ; segment name for call via segment fixup
    84 0000005D 475F43414C4C5F5441-
    84 00000066 424C4500           
    85 0000006A 4E554C4C434F444500      nullcode_text   DB  'NULLCODE',0        ; segment name for first code segment
    86 00000073 434F444500              ncode_text      DB  'CODE',0            ; class name for first code segment
    87                                  
    88 00000078 534D4152544D454D2E-     smartmem_text   DB  'SMARTMEM.XXX',0
    88 00000081 58585800           
    89                                  
    90                                  ;*****************************
    91                                  ;* Code begins               *
    92                                  ;*****************************
    93                                  
    94                                  .CODE
    95                                  
    96                                  ;*****************************
    97                                  ;* PASS1                     *
    98                                  ;*****************************
    99                                  
   100                                  ; main driver for pass 1 of linker
   101                                  ; all registers used or destroyed
   102                                  
   103                                  pass1       PROC
   104                                  
   105                                  %IFNDEF JUNIOR
   106 00000000 31C0                        xor ax,ax
   107 00000002 3806[0000]                  cmp [any_ddl],al          ; see if DDL's used
   108 00000006 7539                        jne p3                  ; yes, bypass this other stuff
   109 00000008 3806[0000]                  cmp [is_smartmem],al      ; see if smartmem option tripped
   110 0000000C 7415                        je  p1                  ; no
   111                                  
   112 0000000E A1[0000]                    mov ax,[lib_count]        ; get count of libraries before adding SmartMem lib
   113 00000011 A3[0000]                    mov [smartmem_count],ax   ; save as current library of SmartMem lib
   114 00000014 BF[8400]                    mov di,OFFSET smartmem_text+12 wrt DGROUP   ; di-> null terminator for check_extension proc
   115 00000017 BA[7800]                    mov dx,OFFSET smartmem_text wrt DGROUP  ; dx -> filename for check_extension proc
   116 0000001A E8(0000)                    call    check_extension
   117                                  
   118 0000001D BF[7800]                    mov di,OFFSET smartmem_text wrt DGROUP  ; add SmartMem library to lib list
   119 00000020 E8(0000)                    call    save_lib_name
   120                                  %ENDIF
   121                                  
   122                                  p1:
   123 00000023 803E[0000]00                cmp byte [is_dosseg],0         ; see if dosseg switch set
   124 00000028 7403                        je  p2                  ; no
   125 0000002A E81D00                      call    make_symbols    ; generate _edata and _end symbol declarations
   126                                  
   127                                  ; see if overlays exist, if so, create $$_OVL_LOOKUP_TABLE segment
   128                                  p2:
   129                                  %IFNDEF JUNIOR
   130 0000002D 30C0                        xor al,al
   131 0000002F 3806[0000]                  cmp [is_anyovls],al       ; see if any overlays
   132 00000033 740C                        je  p3                  ; no
   133 00000035 A3[0000]                    mov [ovl_code_id],ax      ; init overlay code identifier
   134 00000038 0A06[0000]                  or  al,[any_ddl]          ; see if creating or using DDL's
   135 0000003C 7503                        jne p3                  ; yes, don't create fake segments
   136 0000003E E88000                      call    create_lookup   ; create lookup table segment
   137                                  %ENDIF
   138                                  
   139                                  p3:
   140                                   extern create_wllist_temps
   141 00000041 E8(0000)                	call create_wllist_temps
   142 00000044 B001                        mov al,1                ; flag pass 1
   143 00000046 E8(0000)                    call    perform_pass    ; perform pass functions, al flags pass 1 specific routines
   144 00000049 C3                          ret
   145                                  pass1       ENDP
   146                                  
   147                                  ;*****************************
   148                                  ;* MAKE_SYMBOLS              *
   149                                  ;*****************************
   150                                  
   151                                  ; generate a declaration for _edata and _end symbols for DOSSEG switch
   152                                  ; destroys ax,dx,di
   153                                  
   154                                  make_symbols    PROC
   155 0000004A 803E[0000]00                cmp byte [any_ddl],0           ; see if creating or using DDLs
   156 0000004F 7401                        je  ms_1                ; no
   157 00000051 C3                          ret                     ; yes, don't create symbols
   158                                  
   159                                  ms_1:
   160 00000052 06                          push    es              ; save critical register
   161 00000053 BF[0000]                    mov di,OFFSET _edatatext wrt DGROUP ; ds:di -> pubdef name
   162 00000056 803E[0000]00                cmp byte [is_casesense],0      ; see if case sensitive names
   163 0000005B 7403                        je  ms_2                ; no
   164 0000005D BF[0E00]                    mov di,OFFSET lc_edatatext wrt DGROUP   ; ds:di -> lowercase pubdef name
   165                                  
   166                                  ms_2:
   167 00000060 57                          push    di
   168 00000061 B001                        mov al,1                ; flag to make_pubdecl_entry procedure that symbol is pubdef
   169 00000063 E8(0000)                    call    get_pubdecl_entry
   170 00000066 09C0                    	or	ax,ax				; see if zero (use dx)
   171 00000068 7502                    	jne	ms_2a				; no
   172 0000006A 89D0                    	mov	ax,dx
   173                                  
   174                                  ms_2a:
   175 0000006C A3[0000]                    mov [_edata_pubaddr],ax   ; keep public declaration entry segment
   176 0000006F 8EC0                        mov es,ax               ; es -> public declaration entry
   177 00000071 26C6060E0002                mov BYTE PTR [es:14],2  ; flag as a pubdef
   178 00000077 5F                          pop di                  ; ds:di -> pubdef name
   179 00000078 E8(0000)                    call    add_pubdef_name
   180 0000007B 26A30400                    mov [es:4],ax           ; keep offset of entry in lnames block
   181 0000007F 2689160600                  mov [es:6],dx           ; keep segment of entry in lnames block
   182                                  
   183 00000084 BF[0800]                    mov di,OFFSET _end wrt DGROUP   ; ds:di -> pubdef name
   184 00000087 803E[0000]00                cmp byte [is_casesense],0      ; see if case sensitive names
   185 0000008C 7403                        je  ms_3                ; no
   186 0000008E BF[1600]                    mov di,OFFSET lc_end wrt DGROUP ; ds:di -> lowercase pubdef name
   187                                  
   188                                  ms_3:
   189 00000091 57                          push    di
   190 00000092 B001                        mov al,1                ; flag to make_pubdecl_entry procedure that symbol is pubdef
   191 00000094 E8(0000)                    call    get_pubdecl_entry
   192 00000097 09C0                    	or	ax,ax				; see if zero (use dx)
   193 00000099 7502                    	jne	ms_3a				; no
   194 0000009B 89D0                    	mov	ax,dx
   195                                  
   196                                  ms_3a:
   197 0000009D A3[0000]                    mov [_end_pubaddr],ax     ; keep public declaration entry segment
   198 000000A0 8EC0                        mov es,ax               ; es -> public declaration entry
   199 000000A2 26C6060E0002                mov BYTE PTR [es:14],2  ; flag as a pubdef
   200 000000A8 5F                          pop di                  ; ds:di -> pubdef name
   201 000000A9 E8(0000)                    call    add_pubdef_name
   202 000000AC 26A30400                    mov [es:4],ax           ; keep offset of entry in lnames block
   203 000000B0 2689160600                  mov [es:6],dx           ; keep segment of entry in lnames block
   204                                  
   205                                  ; adjust total number of public symbols
   206 000000B5 8306[0000]02                add WORD [pub_sym_count],2
   207 000000BA 8316[0200]00                adc WORD [pub_sym_count+2],0
   208                                  
   209 000000BF 07                          pop es                  ; restore critical register
   210 000000C0 C3                          ret
   211                                  make_symbols    ENDP
   212                                  
   213                                  ;*****************************
   214                                  ;* CREATE_LOOKUP             *
   215                                  ;*****************************
   216                                  
   217                                  ; create lookup table segment for overlaid publics, and
   218                                  ; indirect far call vector segment for overlaid publics
   219                                  ; this is always the first segment declared with overlays,
   220                                  ; so automatically set up the first block
   221                                  ; destroys ax,bx,cx,dx,di,si,es
   222                                  
   223                                  create_lookup   PROC
   224 000000C1 BB4100                      mov bx,SEG_DEFBLK_SIZE  ; number of paragraphs to allocate
   225 000000C4 E8(0000)                    call    alloc_memory    ; get memory for block allocation
   226 000000C7 A3[0000]                    mov [alloc_segdefblk_ptr],ax  ; update last allocated block pointer
   227 000000CA A3[0000]                    mov [first_segdefblk_ptr],ax  ; update first allocate block pointer
   228 000000CD 8EC0                        mov es,ax               ; es == current (new) block segment
   229 000000CF 31C0                        xor ax,ax
   230 000000D1 26A30000                    mov WORD PTR [es:0],ax  ; zero count of entries in block
   231 000000D5 26A30200                    mov WORD PTR [es:2],ax  ; zero pointer to next entry
   232                                  
   233                                  ; create NULL code segment at start of program so that fixups of value zero
   234                                  ; (pointing to first segment) don't exist and fool the overlay manager into
   235                                  ; thinking that it is an overlay relative fixup instead of a root fixup.
   236                                  
   237 000000D9 BE[0000]                    mov si,OFFSET nullcode_segdef wrt DGROUP    ; si -> place to put segdef segment
   238 000000DC B9[6200]                    mov cx,OFFSET nullcode_text-8 wrt DGROUP    ; cx -> segment name, adjusted back 8 bytes to match lnames format
   239 000000DF E82A00                      call    lookup_sub      ; create segment and save segdef value
   240 000000E2 B8[6B00]                    mov ax,OFFSET ncode_text-8 wrt DGROUP   ; get offset to segment class
   241 000000E5 26A30C00                    mov [es:12],ax          ; save offset pointer to segment class
   242 000000E9 26C70606001000              mov WORD PTR [es:6],16  ; make it a paragraph long
   243                                  
   244 000000F0 BE[0000]                    mov si,OFFSET lookup_tbl_segdef wrt DGROUP  ; si -> place to put segdef segment
   245 000000F3 B9[2200]                    mov cx,OFFSET ovlseg_text-8 wrt DGROUP  ; cx -> segment name, adjusted back 8 bytes to match lnames format
   246 000000F6 E81300                      call    lookup_sub      ; create segment and save segdef value
   247                                  
   248 000000F9 BE[0000]                    mov si,OFFSET ind_tbl_segdef wrt DGROUP ; si -> place to put segdef segment
   249 000000FC B9[3600]                    mov cx,OFFSET ovlind_text-8 wrt DGROUP  ; cx -> segment name, adjusted back 8 bytes to match lnames format
   250 000000FF E80A00                      call    lookup_sub      ; create segment and save segdef value
   251                                  
   252 00000102 BE[0000]                    mov si,OFFSET segcall_tbl_segdef wrt DGROUP ; si -> place to put segdef segment
   253 00000105 B9[4C00]                    mov cx,OFFSET ovlscall_text-8 wrt DGROUP    ; cx -> segment name, adjusted back 8 bytes to match lnames format
   254 00000108 E80100                      call    lookup_sub      ; create segment and save segdef value
   255                                  
   256 0000010B C3                          ret
   257                                  create_lookup   ENDP
   258                                  
   259                                  ;*****************************
   260                                  ;* LOOKUP_SUB                *
   261                                  ;*****************************
   262                                  
   263                                  ; subroutine used by create_lookup procedure
   264                                  ; automates the repetitive segment creations
   265                                  ; upon entry si-> variable for segdef entry segment,
   266                                  ; cx holds offset of segment name
   267                                  ; destroys ax,bx,dx,di,es
   268                                  
   269                                  lookup_sub  PROC
   270 0000010C 8E06[0000]                  mov es,[alloc_segdefblk_ptr]  ; es -> segdef block (the only one)
   271 00000110 E8(0000)                    call    init_segdef_entry   ; perform segdef entry initialization code
   272 00000113 8EC7                        mov es,di               ; es -> new segdef entry
   273 00000115 893C                        mov [si],di             ; save -> this segdef entry for resolution time
   274 00000117 FF06[0000]                  inc WORD [seg_count]  ; update count of total discrete segments
   275                                  
   276 0000011B 8CD8                        mov ax,ds               ; update segment and class names, pointing them into warplink data
   277 0000011D 26A30A00                    mov [es:10],ax
   278 00000121 26A30E00                    mov [es:14],ax          ; save segment pointer to segment and class names
   279 00000125 89C8                        mov ax,cx               ; get offset to segment name
   280 00000127 26A30800                    mov [es:8],ax           ; save offset pointer to segment name
   281 0000012B B8[1300]                    mov ax,OFFSET ovlclass_text-8 wrt DGROUP    ; get offset to segment class
   282 0000012E 26A30C00                    mov [es:12],ax          ; save offset pointer to segment class
   283 00000132 26C6061A0060                mov BYTE PTR [es:26],01100000b  ; paragraph aligned, private combine
   284 00000138 C3                          ret
   285                                  lookup_sub  ENDP
   286                                  
   287                                  END
