     1                                  ;*********************************************************************
     2                                  ;*   MLDDL2.ASM                                                      *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          02/12/93                                         *
     6                                  ;*   Model:         Small                                            *
     7                                  ;*   Version:       2.51                                             *
     8                                  ;*   Assembler:     MASM 5.0                                         *
     9                                  ;*   Environment:   MS-DOS 2.x+                                      *
    10                                  ;*                                                                   *
    11                                  ;*   DDL specific code, part 2                                       *
    12                                  ;*                                                                   *
    13                                  ;*********************************************************************
    14                                  
    15                                  ;TITLE   WARPLINK mlddl2
    16                                  ;PAGE    50,80
    17                                  
    18                                  ;.MODEL  SMALL
    19                                  
    20                                  ;*****************************
    21                                  ;* Equates                   *
    22                                  ;*****************************
    23                                  
    24                                  DDL_HEADER_SIZE EQU 128     ; size of DDL header (on 16-byte boundary)
    25                                  MOD_HEADER_SIZE EQU 64      ; size of module header in DDL file (rounded to 16-byte boundary)
    26                                  
    27                                  ;*****************************
    28                                  ;* Include files             *
    29                                  ;*****************************
    30                                  
    31                                  [list -]
    36                                       
    37                                  ;*****************************
    38                                  ;* Public declarations       *
    39                                  ;*****************************
    40                                  
    41                                  ; procedures
    42                                  PUBLIC  write_ddl_dict,ddl_save_libmod_entry,ddl_lib_pass
    43                                  
    44                                  ;*****************************
    45                                  ;* Data begins               *
    46                                  ;*****************************
    47                                  
    48                                  .DATA
    49                                  
    50                                  ;*****************************
    51                                  ;* External declarations     *
    52                                  ;*****************************
    53                                  
    54                                  EXTRN   ddl_header:BYTE,mod_header:BYTE
    55                                  EXTRN   filename:BYTE,obj_handle:WORD,lib_page_size:WORD
    56                                  EXTRN   lib_page_num:WORD,lib_handle:WORD
    57                                  
    58                                  ; word
    59 00000000 0000                    curr_buffpos    DW  0
    60 00000002 ????                    mod_fpos_ptr    DW  ?       ; segment pointer to module file position table
    61 00000004 ????                    ind_fpos_ptr    DW  ?       ; segment pointer to module dictionary index
    62 00000006 0000                    curr_modpub     DW  0       ; count of current module for public processing, relative 0
    63 00000008 ????                    index_size  DW  ?           ; size of directory index
    64 0000000A ????                    pubchar_count   DW  ?       ; count of saved public chars in module
    65 0000000C 0000                    pubpara_count   DW  0       ; running count of paragraphs of publics in dictionary
    66 0000000E ????                    symbuff     DW  ?           ; segment of symbols buffer
    67 00000010 ????                    pubbuff     DW  ?           ; segment of publics buffer
    68 00000012 ????                    current_public  DW  ?       ; current public in module, relative zero
    69                                  
    70                                  ; doublewords
    71 00000014 ????????                pos_adjust  DD  ?           ; adjustment for file positions within a module 
    72                                  
    73                                  ; structures
    74                                  DDL_HEADER_STRUC    STRUC
    75 00000000 ??                          dh_sig1 DB  ?           ; DDL file signature bytes
    76 00000001 ??                          dh_sig2 DB  ?
    77 00000002 ??                          dh_sig3 DB  ?
    78 00000003 ??                          dh_sig4 DB  ?
    79 00000004 ??                          dh_majorver DB  ?       ; major version number
    80 00000005 ??                          dh_minor1   DB  ?       ; minor version number 1
    81 00000006 ??                          dh_minor2   DB  ?       ; minor version number 2
    82 00000007 ??                          dh_minor3   DB  ?       ; minor version alpha
    83 00000008 ????                        dh_hdrsize  DW  ?       ; size of module header
    84 0000000A ????                        dh_loadsize DW  ?       ; size of DDL loader
    85 0000000C ????????                    dh_loadstart    DD  ?   ; file position of start of loader
    86 00000010 ????????                    dh_flags    DD  ?       ; DDL flags
    87                                                              ; bit 0==main module flag
    88                                                              ; bit 1==required root modules flag
    89                                                              ; bit 2==required overlay modules flag
    90                                                              ; bit 3==elective root modules flag
    91                                                              ; bit 4==elective overlay modules flag
    92                                                              ; bit 5==DOSSEG flag
    93                                                              ; bit 6==contains pre-loading routine
    94 00000014 ????????                    dh_op       DD  ?       ; /op option value
    95 00000018 ????                        dh_st       DW  ?       ; /st option value
    96 0000001A ????                        dh_as       DW  ?       ; /as option value
    97 0000001C ????                        dh_os       DW  ?       ; /os option value
    98 0000001E ????                        dh_ol       DW  ?       ; /ol option value
    99 00000020 ??                          dh_mem      DB  ?       ; 0==free mem op, nonzero==alloc mem op
   100 00000021 ??                          dh_minop    DB  ?       ; 0==normal /op, 1==/op:m
   101 00000022 ??                          dh_ox       DB  ?       ; 0==regular memory for op, nonzero==EMS page frame for op
   102 00000023 ??                          dh_r        DB  ?       ; /r option setting
   103 00000024 ??                          dh_cla      DB  ?       ; /cla option setting
   104 00000025 ??                          dh_ou       DB  ?       ; /ou option setting
   105 00000026 ??                          dh_ort      DB  ?       ; /ort setting
   106 00000027 ??                          dh_orp      DB  ?       ; /orp setting
   107 00000028 ????                        dh_modcount DW  ?       ; module count in DDL
   108 0000002A ????                        dh_ddlcount DW  ?       ; count of DDL's in dependency list (for main module)
   109 0000002C ????                        dh_reqroot  DW  ?       ; count of required root modules in DDL
   110 0000002E ????                        dh_reqovl   DW  ?       ; count of required overlay modules in DDL
   111 00000030 ????                        dh_elecroot DW  ?       ; count of elective root modules in DDL
   112 00000032 ????                        dh_elecovl  DW  ?       ; count of elective overlay modules in DDL
   113 00000034 ????????                    dh_ddlstart DD  ?       ; file position of start of DDL dependency list
   114 00000038 ????????                    dh_preload  DD  ?       ; file position of pre-load module
   115 0000003C ????????                    dh_modstart DD  ?       ; file position of start of DDL module file position dword entries
   116 00000040 ????????                    dh_dictstart    DD  ?   ; file position of start of DDL dictionary
   117                                  
   118 00000044 ??                      	dh_ohp3		DB	?		; flag ohp3 use
   119 00000045 ??                      	dh_ohp_flag	DB	?		; nonzero if /ohp allocate to amount flag set
   120 00000046 ??                      	dh_oht_flag	DB	?		; nonzero if /oht allocate to amount flag set
   121 00000047 ??                      	dh_pad		DB	?		; pad value
   122 00000048 ????                    	dh_ohp		DW	?		; /ohp size in K
   123 0000004A ????                    	dh_oht		DW	?		; /oht size in K
   124                                  
   125 0000004C ????????                    dh_reser3   DD  ?       ; reserved for future
   126 00000050 ????????                    dh_reser4   DD  ?       ; reserved for future
   127 00000054 <res 20h>                   dh_oxevar   DB  32 DUP (?)  ; specified /ox environment variable
   128                                  DDL_HEADER_STRUC    ENDS
   129                                  
   130                                  ;istruc_equates ddl_header, DDL_HEADER_STRUC
   131                                  ddl_header.dh_sig1:	equ ddl_header + dh_sig1
   132                                  ddl_header.dh_sig2:	equ ddl_header + dh_sig2
   133                                  ddl_header.dh_sig3:	equ ddl_header + dh_sig3
   134                                  ddl_header.dh_sig4:	equ ddl_header + dh_sig4
   135                                  ddl_header.dh_majorver:	equ ddl_header + dh_majorver
   136                                  ddl_header.dh_minor1:	equ ddl_header + dh_minor1
   137                                  ddl_header.dh_minor2:	equ ddl_header + dh_minor2
   138                                  ddl_header.dh_minor3:	equ ddl_header + dh_minor3
   139                                  ddl_header.dh_hdrsize:	equ ddl_header + dh_hdrsize
   140                                  ddl_header.dh_loadsize:	equ ddl_header + dh_loadsize
   141                                  ddl_header.dh_loadstart:	equ ddl_header + dh_loadstart
   142                                  ddl_header.dh_flags:	equ ddl_header + dh_flags
   143                                  ddl_header.dh_op:	equ ddl_header + dh_op
   144                                  ddl_header.dh_st:	equ ddl_header + dh_st
   145                                  ddl_header.dh_as:	equ ddl_header + dh_as
   146                                  ddl_header.dh_os:	equ ddl_header + dh_os
   147                                  ddl_header.dh_ol:	equ ddl_header + dh_ol
   148                                  ddl_header.dh_mem:	equ ddl_header + dh_mem
   149                                  ddl_header.dh_minop:	equ ddl_header + dh_minop
   150                                  ddl_header.dh_ox:	equ ddl_header + dh_ox
   151                                  ddl_header.dh_r:	equ ddl_header + dh_r
   152                                  ddl_header.dh_cla:	equ ddl_header + dh_cla
   153                                  ddl_header.dh_ou:	equ ddl_header + dh_ou
   154                                  ddl_header.dh_ort:	equ ddl_header + dh_ort
   155                                  ddl_header.dh_orp:	equ ddl_header + dh_orp
   156                                  ddl_header.dh_modcount:	equ ddl_header + dh_modcount
   157                                  ddl_header.dh_ddlcount:	equ ddl_header + dh_ddlcount
   158                                  ddl_header.dh_reqroot:	equ ddl_header + dh_reqroot
   159                                  ddl_header.dh_reqovl:	equ ddl_header + dh_reqovl
   160                                  ddl_header.dh_elecroot:	equ ddl_header + dh_elecroot
   161                                  ddl_header.dh_elecovl:	equ ddl_header + dh_elecovl
   162                                  ddl_header.dh_ddlstart:	equ ddl_header + dh_ddlstart
   163                                  ddl_header.dh_preload:	equ ddl_header + dh_preload
   164                                  ddl_header.dh_modstart:	equ ddl_header + dh_modstart
   165                                  ddl_header.dh_dictstart:	equ ddl_header + dh_dictstart
   166                                  ddl_header.dh_ohp3:	equ ddl_header + dh_ohp3
   167                                  ddl_header.dh_ohp_flag:	equ ddl_header + dh_ohp_flag
   168                                  ddl_header.dh_oht_flag:	equ ddl_header + dh_oht_flag
   169                                  ddl_header.dh_pad:	equ ddl_header + dh_pad
   170                                  ddl_header.dh_ohp:	equ ddl_header + dh_ohp
   171                                  ddl_header.dh_oht:	equ ddl_header + dh_oht
   172                                  ddl_header.dh_reser3:	equ ddl_header + dh_reser3
   173                                  ddl_header.dh_reser4:	equ ddl_header + dh_reser4
   174                                  ddl_header.dh_oxevar:	equ ddl_header + dh_oxevar
   175                                  
   176                                  MOD_HEADER_STRUC    STRUC
   177 00000000 ????????                    mh_flags    DD  ?       ; module flags
   178                                                              ; bit 0==main module flag
   179                                                              ; bit 1==required root module flag
   180                                                              ; bit 2==required overlay module flag
   181                                                              ; bit 3==elective root module flag
   182                                                              ; bit 4==elective overlay module flag
   183                                                              ; bit 6==pre-load module
   184 00000004 ????                        mh_id       DW  ?       ; module identifier
   185 00000006 ????                        mh_segcount DW  ?       ; count of segments in module
   186 00000008 ????                        mh_grpcount DW  ?       ; count of groups in module
   187 0000000A ????                        mh_pubcount DW  ?       ; count of publics
   188 0000000C ????                        mh_comcount DW  ?       ; count of communals
   189 0000000E ????                        mh_extcount DW  ?       ; count of externals
   190 00000010 ????????                    mh_lnames   DD  ?       ; file position of start of lnames name block
   191 00000014 ????????                    mh_segdef   DD  ?       ; file position of start of segment entries
   192 00000018 ????????                    mh_grpdef   DD  ?       ; file position of start of group entries
   193 0000001C ????????                    mh_symbols  DD  ?       ; file position of start of symbols (pub/ext/comdef) name block
   194 00000020 ????????                    mh_pubdef   DD  ?       ; file position of start of pubdef entries
   195 00000024 ????????                    mh_comdef   DD  ?       ; file position of start of comdef entries
   196 00000028 ????????                    mh_extdef   DD  ?       ; file position of start of extdef entries
   197 0000002C ????????                    mh_binary   DD  ?       ; file position of start of binary data
   198 00000030 ??????????????              mh_startup  DB  7 DUP (?)   ; start address if main module in fixup notation
   199 00000037 ??                          mh_pad      DB  ?       ; pad to keep at dword boundary
   200 00000038 ????????                    mh_binfpos  DD  ?       ; file position of each binary entry file position table
   201 0000003C ????????                    mh_reser2   DD  ?       ; reserved for future
   202                                  MOD_HEADER_STRUC    ENDS
   203                                  
   204                                  ;istruc_equates mod_header, MOD_HEADER_STRUC
   205                                  mod_header.mh_flags:	equ mod_header + mh_flags
   206                                  mod_header.mh_id:	equ mod_header + mh_id
   207                                  mod_header.mh_segcount:	equ mod_header + mh_segcount
   208                                  mod_header.mh_grpcount:	equ mod_header + mh_grpcount
   209                                  mod_header.mh_pubcount:	equ mod_header + mh_pubcount
   210                                  mod_header.mh_comcount:	equ mod_header + mh_comcount
   211                                  mod_header.mh_extcount:	equ mod_header + mh_extcount
   212                                  mod_header.mh_lnames:	equ mod_header + mh_lnames
   213                                  mod_header.mh_segdef:	equ mod_header + mh_segdef
   214                                  mod_header.mh_grpdef:	equ mod_header + mh_grpdef
   215                                  mod_header.mh_symbols:	equ mod_header + mh_symbols
   216                                  mod_header.mh_pubdef:	equ mod_header + mh_pubdef
   217                                  mod_header.mh_comdef:	equ mod_header + mh_comdef
   218                                  mod_header.mh_extdef:	equ mod_header + mh_extdef
   219                                  mod_header.mh_binary:	equ mod_header + mh_binary
   220                                  mod_header.mh_startup:	equ mod_header + mh_startup
   221                                  mod_header.mh_pad:	equ mod_header + mh_pad
   222                                  mod_header.mh_binfpos:	equ mod_header + mh_binfpos
   223                                  mod_header.mh_reser2:	equ mod_header + mh_reser2
   224                                  
   225                                  .DATA?
   226                                  
   227                                  ; uninitialized local variables
   228                                  
   229                                  ;*****************************
   230                                  ;* Code begins               *
   231                                  ;*****************************
   232                                  
   233                                  .CODE
   234                                  
   235                                  ;*****************************
   236                                  ;* External declarations     *
   237                                  ;*****************************
   238                                  
   239                                  ; procedures
   240                                  EXTRN   dos_error:NEAR,ddl_pad:NEAR
   241                                  EXTRN   pass1_obj_proc:NEAR
   242                                  EXTRN   print_link_info:NEAR
   243                                  EXTRN   restore_ems_map:NEAR
   244                                  EXTRN   load_libmod:NEAR
   245                                  
   246                                  ;*****************************
   247                                  ;* WRITE_DDL_DICT            *
   248                                  ;*****************************
   249                                  
   250                                  ; upon entry bx==file handle
   251                                  ; destroys ax,bx,cx,dx,si,di,es
   252                                  
   253                                  write_ddl_dict  PROC
   254 00000000 A1[3000]                    mov ax,[ddl_header.dh_elecroot]
   255 00000003 0306[3200]                  add ax,[ddl_header.dh_elecovl]    ; get elective module count
   256 00000007 7501                        jne wdd_init
   257 00000009 C3                          ret                     ; no elective modules, return
   258                                  
   259                                  ; allocate buffer for module file position pointer 4*module count
   260                                  wdd_init:
   261 0000000A A1[2800]                    mov ax,[ddl_header.dh_modcount]
   262 0000000D 89C7                        mov di,ax               ; save module count value
   263 0000000F 83C00F                      add ax,15               ; round up to next paragraph
   264 00000012 D1E8                        shr ax,1
   265 00000014 D1E8                        shr ax,1                ; convert from dword entries to paras
   266 00000016 89C6                        mov si,ax               ; save para count
   267 00000018 8B16[0000]                  mov dx,[buffer_base]
   268 0000001C 29C2                        sub dx,ax               ; compute buffer segment value (just below i/o buffer)
   269 0000001E 8916[0200]                  mov [mod_fpos_ptr],dx     ; save it
   270                                  
   271                                  ; allocate buffer for module dictionary index table 2*module count
   272 00000022 D1EE                        shr si,1                ; convert to word entries
   273 00000024 29F2                        sub dx,si
   274 00000026 8916[0400]                  mov [ind_fpos_ptr],dx     ; save buffer segment value, just below module file position buffer
   275                                  
   276                                  ; seek to module file position table
   277 0000002A 8B16[3C00]                  mov dx,WORD PTR [ddl_header.dh_modstart]
   278 0000002E 8B0E[3E00]                  mov cx,WORD PTR [ddl_header.dh_modstart+2]
   279 00000032 B80042                      mov ax,4200h            ; move file pointer, offset from start
   280 00000035 CD21                        int 21h
   281                                  
   282                                  ; read module file position table into buffer
   283 00000037 89F9                        mov cx,di
   284 00000039 D1E1                        shl cx,1
   285 0000003B D1E1                        shl cx,1                ; 4 bytes/module
   286 0000003D 8CDE                        mov si,ds
   287 0000003F 8E1E[0200]                  mov ds,[mod_fpos_ptr]
   288 00000043 31D2                        xor dx,dx
   289 00000045 B43F                        mov ah,3fh              ; read from file
   290 00000047 CD21                        int 21h
   291 00000049 7303                        jnc wdd_2
   292                                  
   293                                  wdd_doserr:
   294 0000004B E9(0000)                    jmp NEAR PTR dos_error  ; error reading from file
   295                                  
   296                                  wdd_2:
   297 0000004E 39C8                    	cmp ax, cx
   298 00000050 B8FEFF                  	mov ax, -2		; short read code
   299 00000053 75F6                    	jne wdd_doserr
   300 00000055 8EDE                        mov ds,si               ; ds -> warplink data
   301                                  
   302 00000057 31C9                        xor cx,cx
   303 00000059 89CA                        mov dx,cx
   304 0000005B B80242                      mov ax,4202h            ; move file pointer from end of file
   305 0000005E CD21                        int 21h
   306 00000060 A3[4000]                    mov WORD PTR [ddl_header.dh_dictstart],ax ; save dictionary file position
   307 00000063 8916[4200]                  mov WORD PTR [ddl_header.dh_dictstart+2],dx
   308                                  
   309                                  ; write dummy dictionary module index to disk (pre-alloc space)
   310 00000067 01FF                        add di,di               ; di == 2*module count
   311 00000069 893E[0800]                  mov [index_size],di       ; save size of index
   312 0000006D 89F9                        mov cx,di
   313 0000006F 31D2                        xor dx,dx               ; ds:dx -> garbage, doesn't matter
   314 00000071 B440                        mov ah,40h              ; write to file
   315 00000073 CD21                        int 21h
   316 00000075 72D4                        jc  wdd_doserr
   317 00000077 39C8                    	cmp ax, cx
   318 00000079 B82700                  	mov ax, 27h			; insufficient disk space error
   319 0000007C 75CD                    	jne wdd_doserr
   320                                  
   321                                  ; seek to module
   322                                  wdd_seekmod:
   323 0000007E 8E06[0200]                  mov es,[mod_fpos_ptr]
   324 00000082 8B36[0600]                  mov si,[curr_modpub]
   325 00000086 D1E6                        shl si,1
   326 00000088 D1E6                        shl si,1                ; dword/module
   327 0000008A 26AD                        es lodsw   ; get file position low
   328 0000008C 89C2                        mov dx,ax
   329 0000008E A3[1400]                    mov WORD PTR [pos_adjust],ax
   330 00000091 26AD                        es lodsw   ; get file position high
   331 00000093 A3[1600]                    mov WORD PTR [pos_adjust+2],ax
   332 00000096 89C1                        mov cx,ax
   333 00000098 B80042                      mov ax,4200h            ; move file pointer, offset from start
   334 0000009B CD21                        int 21h
   335                                  
   336                                  ; read module header
   337 0000009D BA[0000]                    mov dx,OFFSET mod_header wrt DGROUP
   338 000000A0 B94000                      mov cx,MOD_HEADER_SIZE
   339 000000A3 B43F                        mov ah,3fh              ; read from file
   340 000000A5 CD21                        int 21h
   341 000000A7 72A2                        jc  wdd_doserr
   342 000000A9 39C8                    	cmp ax, cx
   343 000000AB B8FEFF                  	mov ax, -2		; short read code
   344 000000AE 759B                    	jne wdd_doserr
   345                                  
   346 000000B0 31C0                        xor ax,ax
   347 000000B2 A3[0A00]                    mov [pubchar_count],ax    ; init public name char count
   348 000000B5 A3[1200]                    mov [current_public],ax   ; init current public id
   349                                  
   350                                  ; if required module then go to next module
   351 000000B8 A0[0000]                    mov al,BYTE PTR [mod_header.mh_flags]
   352 000000BB 2406                        and al,6                ; get required module flags
   353 000000BD 7403                        je  wdd_compsym         ; elective, process this module
   354                                  
   355                                  to_wdd_nextmod:
   356 000000BF E90B01                      jmp NEAR PTR wdd_nextmod    ; required, try next module
   357                                  
   358                                  ; compute symbol block size (mh_pubdef-mh_symbols)
   359                                  ; since known <64K quantity only deal with low words
   360                                  wdd_compsym:
   361 000000C2 8B0E[2000]                  mov cx,WORD PTR [mod_header.mh_pubdef]
   362 000000C6 2B0E[1C00]                  sub cx,WORD PTR [mod_header.mh_symbols]
   363                                  
   364                                  ; if symbol block size > unused buffer space then flush buffer
   365 000000CA B8E0FF                      mov ax,0ffe0h           ; get buffer size (also allow 16 bytes for padding)
   366 000000CD 2B06[0000]                  sub ax,[curr_buffpos]     ; subtract buffer used
   367 000000D1 39C8                        cmp ax,cx               ; see if enough unused buffer space
   368 000000D3 7303                        jae wdd_seeksym         ; yes
   369                                  
   370 000000D5 E85101                      call    flush_dict_buffer   ; flush buffer to disk
   371                                  
   372                                  ; seek to symbols
   373                                  wdd_seeksym:
   374 000000D8 89CF                        mov di,cx               ; save size of symbols block
   375 000000DA 8B16[1C00]                  mov dx,WORD PTR [mod_header.mh_symbols]
   376 000000DE 8B0E[1E00]                  mov cx,WORD PTR [mod_header.mh_symbols+2]
   377 000000E2 0316[1400]                  add dx,WORD PTR [pos_adjust]
   378 000000E6 130E[1600]                  adc cx,WORD PTR [pos_adjust+2]
   379 000000EA B80042                      mov ax,4200h            ; move file pointer, offset from start
   380 000000ED CD21                        int 21h
   381                                  
   382                                  ; setup buffer to read symbols
   383 000000EF 89FA                        mov dx,di
   384 000000F1 83C20F                      add dx,15               ; round up symbols block size to next para
   385 000000F4 B104                        mov cl,4
   386 000000F6 D3EA                        shr dx,cl
   387 000000F8 A1[0400]                    mov ax,[ind_fpos_ptr]
   388 000000FB 29D0                        sub ax,dx
   389 000000FD A3[0E00]                    mov [symbuff],ax          ; save pointer to symbol buffer, below index buffer
   390                                  
   391                                  ; read symbols block
   392                                  wdd_readsym:
   393 00000100 89F9                        mov cx,di               ; get size of symbols block
   394 00000102 31D2                        xor dx,dx
   395 00000104 8CDF                        mov di,ds
   396 00000106 8ED8                        mov ds,ax               ; ds:dx -> start of symbol buffer
   397 00000108 B43F                        mov ah,3fh              ; read from file
   398 0000010A CD21                        int 21h
   399 0000010C 7246                        jc  wbb_doserr2
   400 0000010E 39C8                    	cmp ax, cx
   401 00000110 B8FEFF                  	mov ax, -2		; short read code
   402 00000113 753F                    	jne wbb_doserr2
   403                                  
   404                                  ; seek to public entries
   405 00000115 8EDF                        mov ds,di               ; ds -> warplink data
   406 00000117 8B16[2000]                  mov dx,WORD PTR [mod_header.mh_pubdef]
   407 0000011B 8B0E[2200]                  mov cx,WORD PTR [mod_header.mh_pubdef+2]
   408 0000011F 0316[1400]                  add dx,WORD PTR [pos_adjust]
   409 00000123 130E[1600]                  adc cx,WORD PTR [pos_adjust+2]
   410 00000127 B80042                      mov ax,4200h            ; move file pointer, offset from start
   411 0000012A CD21                        int 21h
   412                                  
   413                                  ; setup buffer to read public entries, 1 para/public
   414 0000012C C706[0A00]0000              mov word [pubchar_count],0     ; init save public name char count
   415 00000132 A1[0E00]                    mov ax,[symbuff]
   416 00000135 8B0E[0A00]                  mov cx,[mod_header.mh_pubcount]
   417 00000139 E384                        jcxz    to_wdd_nextmod  ; no publics exist
   418 0000013B 29C8                        sub ax,cx
   419 0000013D A3[1000]                    mov [pubbuff],ax
   420                                  
   421                                  ; read public entries
   422 00000140 D1E1                        shl cx,1                ; convert count of publics to byte count
   423 00000142 D1E1                        shl cx,1
   424 00000144 D1E1                        shl cx,1
   425 00000146 D1E1                        shl cx,1
   426 00000148 31D2                        xor dx,dx
   427 0000014A 8CDF                        mov di,ds
   428 0000014C 8ED8                        mov ds,ax               ; ds:dx -> start of public buffer
   429 0000014E B43F                        mov ah,3fh              ; read from file
   430 00000150 CD21                        int 21h
   431 00000152 7303                        jnc wbb_procpub
   432                                  
   433                                  wbb_doserr2:
   434 00000154 E9(0000)                    jmp NEAR PTR dos_error  ; error reading from file
   435                                  
   436                                  ; for each public that is nonlocal
   437                                  ;   look up public symbol name
   438                                  ;   store in buffer
   439                                  wbb_procpub:
   440 00000157 39C8                    	cmp ax, cx
   441 00000159 B8FEFF                  	mov ax, -2		; short read code
   442 0000015C 75F6                    	jne wbb_doserr2
   443 0000015E 8EDF                        mov ds,di
   444 00000160 8B0E[0A00]                  mov cx,[mod_header.mh_pubcount]
   445                                  
   446                                  wbb_publoop:
   447 00000164 31D2                        xor dx,dx               ; init count of chars transferred this pass
   448 00000166 8B36[1200]                  mov si,[current_public]
   449 0000016A D1E6                        shl si,1                ; convert to paras
   450 0000016C D1E6                        shl si,1
   451 0000016E D1E6                        shl si,1
   452 00000170 D1E6                        shl si,1
   453 00000172 8E06[0E00]                  mov es,[symbuff]
   454 00000176 8E1E[1000]                  mov ds,[pubbuff]          ; ds:si -> current public entry
   455 0000017A 8A440E                      mov al,[si+14]       ; get definition flag
   456 0000017D 2403                        and al,3                ; mask off unwanted bits
   457 0000017F 3C02                        cmp al,2                ; see if public/absolute
   458 00000181 7220                        jb  wbb_nextpub         ; no
   459 00000183 8A440F                      mov al,[si+15]       ; get general flags
   460                                  ;***    and al,24h              ; check local bits
   461                                  ;***    jne wbb_nextpub         ; local, don't use
   462                                  
   463                                  ; nonlocal public, transfer to buffer
   464 00000186 8B7404                      mov si,[si+4]        ; get symbol name offset in symbol block
   465 00000189 B8[ssss]                    mov ax,DGROUP
   466 0000018C 8ED8                        mov ds,ax
   467 0000018E 8CC0                        mov ax,es
   468 00000190 8E06[0000]                  mov es,[buffer_base]
   469 00000194 8B3E[0000]                  mov di,[curr_buffpos]     ; es:di -> symbol storage buffer position
   470 00000198 8ED8                        mov ds,ax               ; ds:si -> symbol name
   471                                  
   472                                  wbb_transloop:
   473 0000019A A4                          movsb
   474 0000019B 42                          inc dx                  ; bump count of chars transferred
   475 0000019C 8A44FF                      mov al,[si-1]
   476 0000019F 08C0                        or  al,al               ; see if null terminator transferred
   477 000001A1 75F7                        jne wbb_transloop
   478                                  
   479                                  wbb_nextpub:
   480 000001A3 B8[ssss]                    mov ax,DGROUP
   481 000001A6 8ED8                        mov ds,ax               ; ds -> warplink data
   482 000001A8 0116[0A00]                  add [pubchar_count],dx    ; add in count of chars transferred last public, if any
   483 000001AC 0116[0000]                  add [curr_buffpos],dx     ; update buffer position
   484 000001B0 FF06[1200]                  inc word [current_public]      ; bump count of current public
   485 000001B4 E2AE                        loop    wbb_publoop     ; loop until complete
   486 000001B6 31C0                        xor ax,ax
   487 000001B8 8E06[0000]                  mov es,[buffer_base]
   488                                  
   489                                  wbb_zeroloop:
   490 000001BC 8B3E[0000]                  mov di,[curr_buffpos]     ; get current buffer position
   491 000001C0 F7C70F00                    test    di,0fh          ; see if on paragraph boundary
   492 000001C4 7407                        je  wdd_nextmod         ; yes
   493 000001C6 AA                          stosb                   ; zero out pad byte
   494 000001C7 FF06[0000]                  inc word [curr_buffpos]        ; bump current buffer position
   495 000001CB EBEF                        jmp SHORT wbb_zeroloop  ; pad to paragraph boundary
   496                                  
   497                                  ; setup for next elective module and loop back
   498                                  wdd_nextmod:
   499 000001CD 8E06[0400]                  mov es,[ind_fpos_ptr]
   500 000001D1 8B3E[0600]                  mov di,[curr_modpub]
   501 000001D5 D1E7                        shl di,1                ; es:di -> proper dictionary module index
   502 000001D7 A1[0A00]                    mov ax,[pubchar_count]    ; get count of public chars
   503 000001DA 83C00F                      add ax,15               ; round up to next paragraph
   504 000001DD B104                        mov cl,4
   505 000001DF D3E8                        shr ax,cl               ; convert to paras
   506 000001E1 0106[0C00]                  add [pubpara_count],ax    ; add to running total
   507 000001E5 09C0                        or  ax,ax               ; see if any publics
   508 000001E7 7403                        je  wdd_stashcount      ; no, put a zero in the index
   509 000001E9 A1[0C00]                    mov ax,[pubpara_count]    ; get para offset to end
   510                                  
   511                                  wdd_stashcount:
   512 000001EC AB                          stosw                   ; save public offset to end, or zero if none
   513                                  
   514 000001ED FF06[0600]                  inc word [curr_modpub]         ; bump current module parsing for publics
   515 000001F1 A1[0600]                    mov ax,[curr_modpub]
   516 000001F4 3B06[2800]                  cmp ax,[ddl_header.dh_modcount]
   517 000001F8 7303                        jae wbb_done            ; all modules parsed
   518 000001FA E981FE                      jmp NEAR PTR wdd_seekmod    ; more modules to parse
   519                                  
   520                                  wbb_done:
   521 000001FD E82900                      call    flush_dict_buffer   ; flush pending publics to DDL
   522                                  
   523                                  ; seek to dictionary module index
   524 00000200 8B16[4000]                  mov dx,WORD PTR [ddl_header.dh_dictstart]
   525 00000204 8B0E[4200]                  mov cx,WORD PTR [ddl_header.dh_dictstart+2]
   526 00000208 B80042                      mov ax,4200h            ; move file pointer, offset from start
   527 0000020B CD21                        int 21h
   528                                  
   529                                  ; write dictionary module index to disk
   530 0000020D 8B0E[0800]                  mov cx,[index_size]       ; get size of index
   531 00000211 8CDF                        mov di,ds
   532 00000213 8E1E[0400]                  mov ds,[ind_fpos_ptr]
   533 00000217 31D2                        xor dx,dx
   534 00000219 B440                        mov ah,40h              ; write to file
   535 0000021B CD21                        int 21h
   536 0000021D 7225                        jc  fdb_doserr
   537 0000021F 39C8                    	cmp ax, cx
   538 00000221 B82700                  	mov ax, 27h			; insufficient disk space error
   539 00000224 751E                    	jne fdb_doserr
   540 00000226 8EDF                        mov ds,di               ; restore ds -> warplink data
   541 00000228 C3                          ret
   542                                  write_ddl_dict  ENDP
   543                                  
   544                                  ;*****************************
   545                                  ;* FLUSH_DICT_BUFFER         *
   546                                  ;*****************************
   547                                  
   548                                  ; bx == file handle upon entry
   549                                  ; destroys ax,cx,dx,si
   550                                  
   551                                  flush_dict_buffer   PROC
   552                                  
   553                                  ; seek to end of file for buffer write
   554 00000229 31C9                        xor cx,cx
   555 0000022B 89CA                        mov dx,cx
   556 0000022D B80242                      mov ax,4202h            ; move file pointer from end of file
   557 00000230 CD21                        int 21h
   558                                  
   559 00000232 8CDE                        mov si,ds
   560 00000234 8B0E[0000]                  mov cx,[curr_buffpos]
   561 00000238 31D2                        xor dx,dx
   562 0000023A 8E1E[0000]                  mov ds,[buffer_base]
   563 0000023E B440                        mov ah,40h              ; write to file
   564 00000240 CD21                        int 21h
   565 00000242 7303                        jnc fdb_2
   566                                  
   567                                  fdb_doserr:
   568 00000244 E9(0000)                    jmp NEAR PTR dos_error  ; error writing to file
   569                                  
   570                                  fdb_2:
   571 00000247 39C8                    	cmp ax, cx
   572 00000249 B82700                  	mov ax, 27h			; insufficient disk space error
   573 0000024C 75F6                    	jne fdb_doserr
   574 0000024E 8EDE                        mov ds,si
   575 00000250 C706[0000]0000              mov word [curr_buffpos],0      ; re-init buffer position
   576 00000256 C3                          ret
   577                                  flush_dict_buffer   ENDP
   578                                  
   579                                  ;*****************************
   580                                  ;* DDL_SAVE_LIBMOD_ENTRY     *
   581                                  ;*****************************
   582                                  
   583                                  ; move old library entries to new, low memory, location for UDL use
   584                                  ; destroys ax,cx,es
   585                                  
   586                                  ddl_save_libmod_entry   PROC
   587 00000257 C706[0000]0000              mov word [alloc_libent_ptr],0  ; init last allocated library entry pointer
   588 0000025D A1[0000]                    mov ax,[first_libent_ptr]
   589                                  
   590                                  dsl_loop:
   591 00000260 09C0                        or  ax,ax               ; see if next module
   592 00000262 743E                        je  dsl_done            ; no
   593                                  
   594 00000264 8B0E[0000]                  mov cx,[allocation_base]
   595 00000268 833E[0000]00                cmp word [alloc_libent_ptr],0  ; see if any previously allocated library entries
   596 0000026D 740B                        je  dsl_first           ; no
   597 0000026F 8E06[0000]                  mov es,[alloc_libent_ptr] ; es -> old entry
   598 00000273 26890E1E00                  mov [es:30],cx          ; update pointer
   599 00000278 EB04                        jmp SHORT dsl_2
   600                                  
   601                                  ; first module entry
   602                                  dsl_first:
   603 0000027A 890E[0000]                  mov [first_libent_ptr],cx ; udpate first module pointer
   604                                  
   605                                  dsl_2:
   606 0000027E 890E[0000]                  mov [alloc_libent_ptr],cx ; update last allocated library entry to new save location
   607 00000282 8EC1                        mov es,cx               ; es -> allocation base, new module entry save location
   608 00000284 31FF                        xor di,di               ; es:di -> new location for module entry
   609 00000286 8ED8                        mov ds,ax
   610 00000288 89FE                        mov si,di               ; ds:si -> old module entry to save
   611 0000028A B91000                      mov cx,LIB_MODENT_SIZE*8    ; number of words to transfer (paras*8)
   612 0000028D F3A5                        rep movsw               ; save module entry to new memory location
   613                                  
   614 0000028F B8[ssss]                    mov ax,DGROUP
   615 00000292 8ED8                        mov ds,ax               ; restore ds -> warplink data
   616 00000294 8CC0                        mov ax,es
   617 00000296 83C002                      add ax,LIB_MODENT_SIZE
   618 00000299 A3[0000]                    mov [allocation_base],ax  ; update allocation base past saved module entry
   619 0000029C 26A11E00                    mov ax,[es:30]          ; get pointer to next module entry to be saved
   620 000002A0 EBBE                        jmp SHORT dsl_loop      ; process it
   621                                  
   622                                  dsl_done:
   623 000002A2 C3                          ret
   624                                  
   625                                  ddl_save_libmod_entry   ENDP
   626                                  
   627                                  ;*****************************
   628                                  ;* DDL_LIB_PASS              *
   629                                  ;*****************************
   630                                  
   631                                  ; DDL pass library processing
   632                                  ; destroys ax,bx,cx,dx,di,si,es
   633                                  
   634                                  ddl_lib_pass    PROC
   635 000002A3 C706[0000]FFFF              mov word [current_lib],-1      ; force library to load on first compare
   636 000002A9 A1[0000]                    mov ax,[first_libent_ptr] ; get pointer to first library module entry
   637                                  
   638                                  dlp_loop:
   639 000002AC 09C0                        or  ax,ax               ; check that segment is nonzero
   640 000002AE 7501                        jne dlp_1               ; yes
   641 000002B0 C3                          ret                     ; segment is zero, all done processing library modules
   642                                  
   643                                  dlp_1:
   644 000002B1 8EC0                        mov es,ax               ; es -> library module entry
   645 000002B3 50                          push    ax              ; save entry segment
   646                                  
   647 000002B4 26A10000                    mov ax,[es:0]           ; get library
   648 000002B8 3B06[0000]                  cmp ax,[current_lib]      ; see if matches current library
   649 000002BC 7502                        jne dlp_newlib          ; no
   650 000002BE EB7C                        jmp NEAR PTR  dlp_2     ; yes
   651                                  
   652                                  dlp_newlib:
   653 000002C0 833E[0000]FF                cmp word [current_lib],-1      ; see if first time through loop
   654 000002C5 740F                        je  dlp_1a              ; yes
   655 000002C7 89C1                        mov cx,ax               ; save library in cx
   656 000002C9 8B1E[0000]                  mov bx,[obj_handle]       ; get file handle of previously opened library
   657 000002CD B43E                        mov ah,3eh              ; close file
   658 000002CF CD21                        int 21h
   659 000002D1 E8(0000)                    call    restore_ems_map
   660                                  
   661 000002D4 89C8                        mov ax,cx               ; get library back in ax
   662                                  
   663                                  dlp_1a:
   664 000002D6 A3[0000]                    mov [current_lib],ax      ; update current library to reflect library being processed
   665                                  
   666                                  ; get and open library indicated by library module entry
   667 000002D9 06                          push    es              ; save critical register
   668 000002DA 31C9                        xor cx,cx               ; cx == library entry counter
   669 000002DC A1[0000]                    mov ax,[first_libblk_ptr] ; get first object name block
   670                                  
   671                                  dlp_1b:
   672 000002DF BE0400                      mov si,4                ; si -> first name in block
   673 000002E2 8EC0                        mov es,ax               ; point extra segment at object name block
   674                                  
   675                                  dlp_lib_loop:
   676 000002E4 268A04                      mov al,[es:si]          ; get flag byte
   677 000002E7 24C0                        and al,0c0h             ; only get overlay bits
   678 000002E9 A2[0000]                    mov [obj_ovl_flag],al     ; save overlay status for module
   679 000002EC 2440                        and al,40h              ; get nonvector root call status
   680 000002EE A2[0000]                    mov [nonovl_rvect],al     ; save it to global variable
   681 000002F1 46                          inc si                  ; adjust past prepended flag byte in entry
   682 000002F2 B81001                      mov ax,LIB_NAMBLK_BYSIZE    ; size of block in bytes
   683 000002F5 262B060000                  sub ax,[es:0]           ; minus free space, ax == end of used namelist
   684 000002FA 39F0                        cmp ax,si               ; check that position in list is below end
   685 000002FC 7706                        ja  dlp_lib2            ; not at end yet, check namelist position
   686                                  
   687 000002FE 26A10200                    mov ax,[es:2]           ; get pointer to next block
   688 00000302 EBDB                        jmp SHORT dlp_1b
   689                                  
   690                                  dlp_lib2:
   691 00000304 3B0E[0000]                  cmp cx,[current_lib]      ; see if at proper position in library name block
   692 00000308 740E                        je  dlp_lib4            ; yes
   693                                  
   694                                  ; not at proper position, gobble bytes until next library name
   695                                  dlp_lib_gobble:
   696 0000030A 268A04                      mov al,[es:si]          ; check if at end of library name in block
   697 0000030D 08C0                        or  al,al
   698 0000030F 7403                        je  dlp_lib3            ; yes
   699 00000311 46                          inc si                  ; bump to next char
   700 00000312 EBF6                        jmp dlp_lib_gobble
   701                                  
   702                                  dlp_lib3:
   703 00000314 46                          inc si                  ; bump to first char of next name in block
   704 00000315 41                          inc cx                  ; bump count of entry scanned
   705 00000316 EBCC                        jmp SHORT dlp_lib_loop  ; and loop back to try next namelist position
   706                                  
   707                                  dlp_lib4:
   708 00000318 1E                          push    ds              ; save critical register
   709 00000319 1E                          push    ds
   710 0000031A 06                          push    es
   711 0000031B 1F                          pop ds                  ; ds:si -> library name in block
   712 0000031C 07                          pop es
   713 0000031D BF[0000]                    mov di,OFFSET filename wrt DGROUP   ; es:di -> destination of library name
   714                                  
   715                                  dlp_transfer:
   716 00000320 A4                          movsb                   ; transfer a char from the block to filename
   717 00000321 807CFF00                    cmp BYTE PTR [si-1],0   ; zero byte signals end of transfer
   718 00000325 75F9                        jne dlp_transfer        ; nonzero, keep looping
   719                                  
   720 00000327 1F                          pop ds                  ; restore critical register
   721 00000328 07                          pop es                  ; restore critical register
   722 00000329 E8(0000)                    call    print_link_info ; print library name, if applicable
   723 0000032C BA[0000]                    mov dx,OFFSET filename wrt DGROUP   ; DS:DX -> ASCIIZ file specification
   724 0000032F B8003D                      mov ax,3d00h            ; open file with read access
   725 00000332 CD21                        int 21h
   726 00000334 E8(0000)                    call    restore_ems_map
   727 00000337 722A                        jc  dlp_doserr          ; error occurred
   728                                  
   729 00000339 A3[0000]                    mov [obj_handle],ax       ; save library file handle
   730                                  
   731                                  dlp_2:
   732 0000033C 26A10400                    mov ax,[es:4]           ; get library page size
   733 00000340 A3[0000]                    mov [lib_page_size],ax    ; save to memory variable
   734 00000343 26A10200                    mov ax,[es:2]           ; get page number (location in lib file)
   735 00000347 A3[0000]                    mov [lib_page_num],ax     ; save to memory variable
   736                                  
   737 0000034A A1[0000]                    mov ax,[obj_handle]       ; get file handle into lib_handle
   738 0000034D A3[0000]                    mov [lib_handle],ax
   739                                  
   740 00000350 268B1E0600                  mov bx,[es:6]           ; get module length
   741 00000355 E8(0000)                    call    load_libmod     ; load the module
   742 00000358 E8(0000)                    call    pass1_obj_proc  ; pass 1 process loaded library module
   743                                  
   744 0000035B 07                          pop es                  ; es -> library module entry
   745 0000035C 26A11E00                    mov ax,[es:30]          ; get pointer to next entry
   746 00000360 E949FF                      jmp NEAR PTR dlp_loop   ; loop back to process it
   747                                  
   748                                  dlp_doserr:
   749 00000363 E9(0000)                    jmp NEAR PTR dos_error  ; error occurred
   750                                  
   751                                  ddl_lib_pass    ENDP
   752                                  
   753                                  END
