     1                                  ;*********************************************************************
     2                                  ;*   MLQUICK.ASM                                                     *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          01/01/93                                         *
     6                                  ;*   Model:         Small                                            *
     7                                  ;*   Version:       2.50                                             *
     8                                  ;*   Assembler:     MASM 5.0                                         *
     9                                  ;*   Environment:   MS-DOS 2.x+                                      *
    10                                  ;*                                                                   *
    11                                  ;*   Quick linker code                                               *
    12                                  ;*                                                                   *
    13                                  ;*********************************************************************
    14                                  
    15                                  ;TITLE   WARPLINK mlquick
    16                                  ;PAGE    50,80
    17                                  
    18                                  ;.MODEL  SMALL
    19                                  
    20                                  ;*****************************
    21                                  ;* Include files             *
    22                                  ;*****************************
    23                                  
    24                                  [list -]
    29                                       
    30                                  ;*****************************
    31                                  ;* Public declarations       *
    32                                  ;*****************************
    33                                  
    34                                  ; procedures
    35                                  PUBLIC	check_qlk,read_qlk_libname,read_qlk_mod_info,read_qlk_unres
    36                                  PUBLIC	write_qlk_libname,write_qlk_mod_info,write_qlk_unres
    37                                  PUBLIC	write_qlk_lib_info,is_qlk_file,write_qlk_modsize
    38                                  PUBLIC	delete_qlk_file
    39                                  
    40                                  ; variables
    41                                  PUBLIC	writing_qlk_flag,reading_qlk_flag,no_qlk_modules
    42                                  
    43                                  ;*****************************
    44                                  ;* Data begins               *
    45                                  ;*****************************
    46                                  
    47                                  ; initialized data     
    48                                  .DATA
    49                                  
    50                                  ;*****************************
    51                                  ;* External declarations     *
    52                                  ;*****************************
    53                                  
    54                                  ; variables
    55                                  EXTRN   filename:BYTE
    56                                  EXTRN	lib_page_size:WORD,lib_page_num:WORD
    57                                  EXTRN	module_flag:BYTE,libmod_obj_flag:BYTE,lib_read_amt:WORD
    58                                  EXTRN	parfilename:BYTE,exe_ext_ptr:WORD
    59                                  
    60                                  EVEN
    61                                  
    62                                  ; bytes
    63 00000000 00                      writing_qlk_flag	DB	0	; nonzero if writing to QLK file
    64 00000001 00                      reading_qlk_flag	DB	0	; nonzero if reading from QLK file
    65                                  
    66                                  ; words
    67 00000002 0000                    qlk_handle	DW	0			; handle of open QLK file
    68 00000004 0000                    qlk_buffpos	DW	0			; current read/write position in qlk buffer
    69 00000006 0000                    qlk_readpos	DW	0			; read position of qlk file
    70                                  
    71                                  ; uninitialized data
    72                                  .DATA?
    73                                  
    74                                  EVEN
    75                                   global to_zero_initialise_2, to_zero_initialise_2_length_words
    76                                  to_zero_initialise_2:
    77                                  
    78                                  ; byte strings
    79 00000000 <res 80h>               qlk_name    DB  128 DUP (?) ; QLK (QuickLinker) file name, including any path
    80 00000080 <res 12Ch>              qlk_buffer	DB	300 DUP (?)	; QLK read/write buffer
    81                                  EVEN
    82                                  to_zero_initialise_2_length_words equ ($ - to_zero_initialise_2 + 1) / 2
    83                                  
    84                                  ; bytes
    85 000001AC ??                      no_qlk_modules	DB	?		; nonzero if no library modules for library in QLK file
    86                                  
    87                                  ;*****************************
    88                                  ;* Constant data             *
    89                                  ;*****************************
    90                                  
    91                                  .CONST
    92                                  
    93 00000000 514C4B                  qlk_text	DB	"QLK"
    94                                  
    95                                  ;*****************************
    96                                  ;* Code begins               *
    97                                  ;*****************************
    98                                       
    99                                  .CODE
   100                                  
   101                                  ;*****************************
   102                                  ;* External declarations     *
   103                                  ;*****************************
   104                                  
   105                                  EXTRN   link_error:NEAR,dos_error:NEAR,restore_ems_map:NEAR
   106                                  EXTRN	get_xxx_name:NEAR,file_not_found:NEAR,set_exe_name:NEAR
   107                                  
   108                                  ;*****************************
   109                                  ;* IS_QLK_FILE               *
   110                                  ;*****************************
   111                                  
   112                                  ; returns carry flag set is QLK does not exist, reset if does
   113                                  ; destroys ax,bx,dx
   114                                  
   115                                  is_qlk_file	PROC
   116 00000000 51                      	push	cx				; save critical registers
   117 00000001 56                      	push	si
   118 00000002 57                      	push	di
   119 00000003 06                      	push	es
   120                                  
   121                                  ; copy parfilename to qlk_buffer variable
   122 00000004 1E                      	push	ds
   123 00000005 07                      	pop	es
   124 00000006 B94000                  	mov	cx,64
   125 00000009 BE[0000]                	mov	si,OFFSET parfilename wrt DGROUP
   126 0000000C BF[8000]                	mov	di,OFFSET qlk_buffer wrt DGROUP
   127 0000000F F3A5                    	rep	movsw
   128                                  
   129 00000011 FF36[0000]              	push	WORD [exe_name]	; save exe_name in case is null and have to set it
   130 00000015 FF36[0000]              	push	word [exe_ext_ptr]		; save exe name info
   131 00000019 803E[0000]00            	cmp	BYTE [exe_name],0	; see if exe name supplied (for get_xxx_name use)
   132 0000001E 7503                    	jne	iqf_exe_ok			; yes
   133 00000020 E8(0000)                	call	set_exe_name	; set the EXE name temporarily
   134                                  
   135                                  iqf_exe_ok:
   136 00000023 BB[0000]                	mov	bx,OFFSET qlk_text wrt DGROUP	; bx -> proper extension
   137 00000026 BF[0000]                    mov di,OFFSET qlk_name wrt DGROUP   ; di -> place to put ILF name
   138 00000029 89FA                    	mov	dx,di				; ds:dx -> filespec
   139 0000002B E8(0000)                    call    get_xxx_name    ; get QLK name
   140 0000002E B8023D                      mov ax,3d02h            ; open file for reading/writing
   141 00000031 CD21                        int 21h
   142 00000033 E8(0000)                    call    restore_ems_map
   143 00000036 7302                    	jnc	iqf_close			; success open, close it
   144 00000038 EB06                    	jmp	SHORT iqf_ret
   145                                  
   146                                  ; close the opened QLK file
   147                                  iqf_close:
   148 0000003A 89C3                    	mov	bx,ax
   149 0000003C B43E                    	mov	ah,3eh
   150 0000003E CD21                    	int	21h
   151                                  
   152                                  iqf_ret:
   153                                  
   154                                  ; copy qlk_buffer to parfilename variable
   155 00000040 1E                      	push	ds
   156 00000041 07                      	pop	es
   157 00000042 B94000                  	mov	cx,64
   158 00000045 BF[0000]                	mov	di,OFFSET parfilename wrt DGROUP
   159 00000048 BE[8000]                	mov	si,OFFSET qlk_buffer wrt DGROUP
   160 0000004B F3A5                    	rep	movsw
   161                                  
   162 0000004D 8F06[0000]              	pop	word [exe_ext_ptr]			; restore exe name info
   163 00000051 8F06[0000]              	pop	WORD [exe_name]	; restore exe_name to original null status if modified
   164 00000055 07                      	pop	es					; restore critical registers
   165 00000056 5F                      	pop	di
   166 00000057 5E                      	pop	si
   167 00000058 59                      	pop	cx
   168 00000059 C3                      	ret
   169                                  is_qlk_file	ENDP
   170                                  
   171                                  ;*****************************
   172                                  ;* CHECK_QLK                 *
   173                                  ;*****************************
   174                                  
   175                                  ; check if QLK file exists, if not create
   176                                  ; if exists, open
   177                                  ; destroys ax,bx,cx,dx,si,di,es
   178                                  
   179                                  check_qlk	PROC
   180 0000005A BB[0000]                	mov	bx,OFFSET qlk_text wrt DGROUP	; bx -> proper extension
   181 0000005D BF[0000]                    mov di,OFFSET qlk_name wrt DGROUP   ; di -> place to put ILF name
   182 00000060 89FA                    	mov	dx,di				; ds:dx -> filespec
   183 00000062 E8(0000)                    call    get_xxx_name    ; get QLK name
   184 00000065 B8023D                      mov ax,3d02h            ; open file for reading/writing
   185 00000068 CD21                        int 21h
   186 0000006A E8(0000)                    call    restore_ems_map
   187 0000006D BA0100                  	mov	dx,1				; flag reading from qlk file, do NOT change flags
   188 00000070 7311                        jnc cq_qlk_found        ; file found okay
   189                                  
   190                                  ; QLK does not exist, build a new one
   191                                  cq_build:
   192 00000072 BA[0000]                    mov dx,OFFSET qlk_name wrt DGROUP	; ds:dx -> filespec
   193 00000075 31C9                        xor cx,cx				; normal file
   194 00000077 B43C                        mov ah,3ch				; create or truncate file
   195 00000079 CD21                        int 21h
   196 0000007B E8(0000)                    call    restore_ems_map
   197 0000007E BA0001                  	mov	dx,100h				; flag writing to qlk file, do NOT change flags
   198 00000081 720C                    	jc	to_doserr			; error occured
   199                                  
   200                                  ; QLK file exists
   201                                  ; ax holds file handle of QLK file
   202                                  cq_qlk_found:
   203 00000083 A3[0200]                    mov [qlk_handle],ax       ; save handle of QLK file
   204 00000086 8836[0000]              	mov	[writing_qlk_flag],dh	; set qlk read/write flags
   205 0000008A 8816[0100]              	mov	[reading_qlk_flag],dl
   206 0000008E C3                      	ret
   207                                  
   208                                  to_doserr:
   209 0000008F E9(0000)                    jmp NEAR PTR dos_error	; dos error
   210                                  
   211                                  check_qlk	ENDP
   212                                  
   213                                  ;*****************************
   214                                  ;* READ_QLK_LIBNAME          *
   215                                  ;*****************************
   216                                  
   217                                  ; read the QuickLinker file for library name
   218                                  ; transfer to filename variable
   219                                  ; returns carry flag set if no more library names
   220                                  ; destroys ax,bx,cx,dx,si,di,es
   221                                  
   222                                  read_qlk_libname	PROC
   223 00000092 30C0                    	xor	al,al
   224 00000094 A2[AC01]                	mov	[no_qlk_modules],al	; init no library modules flag
   225 00000097 8B1E[0200]              	mov	bx,[qlk_handle]
   226 0000009B 8B16[0600]              	mov	dx,[qlk_readpos]
   227 0000009F 31C9                    	xor	cx,cx
   228 000000A1 B442                        mov ah,42h				; move file pointer, offset from file start
   229 000000A3 CD21                        int 21h
   230                                  
   231 000000A5 BA[8000]                	mov	dx,OFFSET qlk_buffer wrt DGROUP
   232 000000A8 B98300                  	mov	cx,131
   233 000000AB B43F                    	mov	ah,3fh				; read file
   234 000000AD CD21                    	int	21h
   235 000000AF E8(0000)                    call    restore_ems_map
   236 000000B2 7266                    	jc	rql_doserr			; error occured
   237 000000B4 39C8                    	cmp ax, cx
   238 000000B6 B8FEFF                  	mov ax, -2		; short read code
   239 000000B9 755F                    	jne rql_doserr
   240                                  
   241 000000BB 813E[8000]40FF          	cmp	WORD [qlk_buffer],0ff40h	; see if library name
   242 000000C1 7408                    	je	rql_islib			; yes
   243                                  
   244                                  ; no more libraries
   245                                  rql_fail:
   246 000000C3 C706[0400]0000          	mov	word [qlk_buffpos],0		; re-init qlk read/write buffer position
   247 000000C9 F9                      	stc						; flag failure
   248 000000CA C3                      	ret
   249                                  
   250                                  rql_islib:
   251 000000CB 8306[0600]02            	add	word [qlk_readpos],2			; adjust for prepended flag word
   252                                  
   253                                  ; transfer file name
   254 000000D0 1E                      	push	ds
   255 000000D1 07                      	pop	es
   256 000000D2 BF[0000]                	mov	di,OFFSET filename wrt DGROUP
   257 000000D5 BE[8200]                	mov	si,OFFSET qlk_buffer+2 wrt DGROUP	; point past flag byte
   258                                  
   259                                  rql_transloop:
   260 000000D8 A4                      	movsb
   261 000000D9 FF06[0600]              	inc	word [qlk_readpos]
   262 000000DD 807CFF00                	cmp	BYTE PTR [si-1],0	; see if null terminator transferred
   263 000000E1 75F5                    	jne	rql_transloop
   264                                  
   265                                  ; at library system info flag byte or start of next entry
   266 000000E3 8B04                    	mov	ax,[si]				; get next entry value, if is next
   267                                  
   268                                  ; this could be the start of another library, or unresolved externals
   269                                  ; if there were no modules used from the library
   270                                  ; check for 0ff10h or 0ff40h word value
   271 000000E5 3D10FF                  	cmp	ax,0ff10h			; check for unresolveds
   272 000000E8 7419                    	je	rql_scan			; yes
   273 000000EA 3D40FF                  	cmp	ax,0ff40h			; check for next library
   274 000000ED 7505                    	jne	rql_update			; not next library
   275 000000EF A2[AC01]                	mov	[no_qlk_modules],al	; flag that no library modules for library
   276 000000F2 EB0F                    	jmp	SHORT rql_scan
   277                                  
   278                                  rql_update:
   279 000000F4 8B4401                  	mov	ax,[si+1]			; get library page size
   280 000000F7 FF06[0600]              	inc	word [qlk_readpos]			; adjust for prepended flag byte
   281 000000FB A3[0000]                	mov	[lib_page_size],ax	; save it
   282 000000FE 8306[0600]02            	add	word [qlk_readpos],2		; adjust for library page size
   283                                  
   284                                  ; scan to start of module information in qlk file
   285                                  rql_scan:
   286 00000103 8B1E[0200]              	mov	bx,[qlk_handle]
   287 00000107 8B16[0600]              	mov	dx,[qlk_readpos]
   288 0000010B 31C9                    	xor	cx,cx
   289 0000010D B80042                      mov ax,4200h			; move file pointer, offset from file start
   290 00000110 CD21                        int 21h
   291                                  
   292 00000112 C706[0400]2C01          	mov	word [qlk_buffpos],300		; init buffer position to force read
   293 00000118 F8                      	clc						; flag success
   294 00000119 C3                      	ret
   295                                  
   296                                  rql_doserr:
   297 0000011A E96F02                  	jmp	NEAR PTR qlk_doserr
   298                                  
   299                                  read_qlk_libname	ENDP
   300                                  
   301                                  ;*****************************
   302                                  ;* READ_QLK_MOD_INFO         *
   303                                  ;*****************************
   304                                  
   305                                  ; read the QuickLinker file for module info
   306                                  ; updates current_lib,lib_page_num
   307                                  ; returns carry flag set if no more modules, reset and variables updated otherwise
   308                                  ; destroys ax,bx,cx,dx
   309                                  
   310                                  read_qlk_mod_info	PROC
   311 0000011D BA[8000]                	mov	dx,OFFSET qlk_buffer wrt DGROUP
   312 00000120 8B1E[0400]              	mov	bx,[qlk_buffpos]
   313 00000124 81FB2501                	cmp	bx,293				; see if need to read in info
   314 00000128 722B                    	jb	rqm_2				; no
   315                                  
   316 0000012A 8B1E[0200]              	mov	bx,[qlk_handle]
   317 0000012E 8B16[0600]              	mov	dx,[qlk_readpos]
   318 00000132 31C9                    	xor	cx,cx
   319 00000134 B80042                      mov ax,4200h			; move file pointer, offset from file start
   320 00000137 CD21                        int 21h
   321                                  
   322 00000139 BA[8000]                	mov	dx,OFFSET qlk_buffer wrt DGROUP
   323 0000013C B92C01                  	mov	cx,300
   324 0000013F B43F                    	mov	ah,3fh				; read file
   325 00000141 CD21                    	int	21h
   326 00000143 E8(0000)                    call    restore_ems_map
   327 00000146 7258                    	jc	rqm_doserr			; error occured
   328 00000148 39C8                    	cmp ax, cx
   329 0000014A B8FEFF                  	mov ax, -2		; short read code
   330 0000014D 7551                    	jne rqm_doserr
   331                                  
   332 0000014F 31DB                    	xor	bx,bx
   333 00000151 891E[0400]              	mov	[qlk_buffpos],bx		; init buffer position
   334                                  
   335                                  rqm_2:
   336 00000155 31C0                    	xor	ax,ax				; pre-set no module info indicator
   337 00000157 01D3                    	add	bx,dx
   338 00000159 A2[0000]                	mov	[obj_ovl_flag],al		; init variables
   339 0000015C A2[0000]                	mov	[nonovl_rvect],al
   340 0000015F A2[0000]                	mov	[libmod_obj_flag],al
   341 00000162 8A07                    	mov	al,[bx]				; get module info flag
   342 00000164 A820                    	test	al,20h			; see if module info flag
   343 00000166 7436                    	je	rqm_fail			; not module info, fail
   344                                  
   345                                  ; set appropriate flags for module
   346 00000168 A804                    	test	al,4			; see if overlaid
   347 0000016A 740E                    	je	rqm_4				; no
   348 0000016C C606[0000]C0            	mov	byte [obj_ovl_flag],0c0h	; flag overlaid
   349                                  
   350 00000171 A802                    	test	al,2			; see if root vectoring
   351 00000173 7505                    	jne	rqm_4				; no
   352 00000175 C606[0000]40            	mov	byte [nonovl_rvect],40h	; flag root vectoring
   353                                  
   354                                  rqm_4:
   355 0000017A 2401                    	and	al,1				; see if module
   356 0000017C A2[0000]                	mov	[module_flag],al		; flag module
   357                                  
   358 0000017F B80700                  	mov	ax,7
   359 00000182 0106[0400]              	add	[qlk_buffpos],ax		; adjust buffer position
   360 00000186 0106[0600]              	add	[qlk_readpos],ax		; adjust file position
   361 0000018A 8B4703                  	mov	ax,[bx+3]			; get current library number
   362 0000018D A3[0000]                	mov	[current_lib],ax		; update variable
   363 00000190 8B4701                  	mov	ax,[bx+1]			; get library page
   364 00000193 A3[0000]                	mov	[lib_page_num],ax
   365 00000196 8B4705                  	mov	ax,[bx+5]			; get # of bytes to read for file
   366 00000199 A3[0000]                	mov	[lib_read_amt],ax
   367 0000019C F8                      	clc						; flag success
   368 0000019D C3                      	ret
   369                                  
   370                                  rqm_fail:
   371 0000019E F9                      	stc						; flag failure
   372 0000019F C3                      	ret
   373                                  
   374                                  rqm_doserr:
   375 000001A0 E9E901                  	jmp	NEAR PTR qlk_doserr
   376                                  
   377                                  read_qlk_mod_info	ENDP
   378                                  
   379                                  ;*****************************
   380                                  ;* READ_QLK_UNRES            *
   381                                  ;*****************************
   382                                  
   383                                  ; read the QuickLinker file for unresolved externals
   384                                  ; if current unresolved > saved unresolved change reading qlk flag to writing
   385                                  ; destroys ax,bx,cx,dx
   386                                  
   387                                  read_qlk_unres	PROC
   388 000001A3 BA[8000]                	mov	dx,OFFSET qlk_buffer wrt DGROUP
   389 000001A6 8B1E[0400]              	mov	bx,[qlk_buffpos]
   390 000001AA 81FB2801                	cmp	bx,296				; see if need to read in info
   391 000001AE 722B                    	jb	rqu_2				; no
   392                                  
   393 000001B0 8B1E[0200]              	mov	bx,[qlk_handle]
   394 000001B4 8B16[0600]              	mov	dx,[qlk_readpos]
   395 000001B8 31C9                    	xor	cx,cx
   396 000001BA B80042                      mov ax,4200h			; move file pointer, offset from file start
   397 000001BD CD21                        int 21h
   398                                  
   399 000001BF BA[8000]                	mov	dx,OFFSET qlk_buffer wrt DGROUP
   400 000001C2 8B1E[0200]              	mov	bx,[qlk_handle]
   401 000001C6 B90400                  	mov	cx,4
   402 000001C9 B43F                    	mov	ah,3fh				; read file
   403 000001CB CD21                    	int	21h
   404 000001CD E8(0000)                    call    restore_ems_map
   405 000001D0 7232                    	jc	rqu_doserr			; error occured
   406 000001D2 39C8                    	cmp ax, cx
   407 000001D4 B8FEFF                  	mov ax, -2		; short read code
   408 000001D7 752B                    	jne rqu_doserr
   409                                  
   410 000001D9 31DB                    	xor	bx,bx
   411                                  
   412                                  rqu_2:
   413 000001DB 01D3                    	add	bx,dx
   414 000001DD A1[0000]                	mov	ax,WORD PTR [tot_sym_count]
   415 000001E0 2B06[0000]              	sub	ax,WORD PTR [pub_sym_count]
   416 000001E4 3B4702                  	cmp	ax,[bx+2]			; check current unresolved count against saved
   417 000001E7 7701                    	ja	rqu_fail
   418 000001E9 C3                      	ret
   419                                  
   420                                  ; more unresolved externals than previously, append new lib information
   421                                  ; scan to start of unresolved info (end of module info) in qlk file
   422                                  rqu_fail:
   423 000001EA 8B1E[0200]              	mov	bx,[qlk_handle]
   424 000001EE 8B16[0600]              	mov	dx,[qlk_readpos]
   425 000001F2 31C9                    	xor	cx,cx
   426 000001F4 B80042                      mov ax,4200h			; move file pointer, offset from file start
   427 000001F7 CD21                        int 21h
   428 000001F9 C606[0100]00            	mov	byte [reading_qlk_flag],0	; change status of reading flags to writing
   429 000001FE C606[0000]01            	mov	byte [writing_qlk_flag],1
   430 00000203 C3                      	ret
   431                                  
   432                                  rqu_doserr:
   433 00000204 E98501                  	jmp	NEAR PTR qlk_doserr
   434                                  
   435                                  read_qlk_unres	ENDP
   436                                  
   437                                  ;*****************************
   438                                  ;* WRITE_QLK_LIBNAME         *
   439                                  ;*****************************
   440                                  
   441                                  ; write library name to QuickLinker file
   442                                  ; destroys ax,bx,cx,dx
   443                                  
   444                                  write_qlk_libname	PROC
   445 00000207 8B1E[0400]              	mov	bx,[qlk_buffpos]
   446 0000020B BA[8000]                	mov	dx,OFFSET qlk_buffer wrt DGROUP
   447 0000020E 09DB                    	or	bx,bx				; see if module info in buffer to flush
   448 00000210 7403                    	je	wql_2				; no
   449                                  
   450 00000212 E8F700                  	call	flush_qlk_buffer	; flush remaining module info bytes
   451                                  
   452                                  ; write library word flag (0FF40h)
   453                                  wql_2:
   454 00000215 8B1E[0200]              	mov	bx,[qlk_handle]
   455 00000219 C706[8000]40FF          	mov	WORD [qlk_buffer],0ff40h
   456 0000021F B90200                  	mov	cx,2
   457 00000222 B440                    	mov	ah,40h				; write to file
   458 00000224 CD21                    	int	21h
   459 00000226 E8(0000)                    call    restore_ems_map
   460 00000229 722B                    	jc	wql_doserr			; error occured
   461 0000022B 39C8                    	cmp ax, cx
   462 0000022D B82700                  	mov ax, 27h			; insufficient disk space error
   463 00000230 7524                    	jne wql_doserr
   464                                  
   465                                  ; write library name
   466 00000232 B8[0000]                	mov	ax,OFFSET filename wrt DGROUP
   467 00000235 89C2                    	mov	dx,ax
   468 00000237 93                      	xchg	bx,ax			; bx -> filename, ax==file handle
   469 00000238 31C9                    	xor	cx,cx				; cx holds char count of filename
   470                                  
   471                                  wql_loop:
   472 0000023A 41                      	inc	cx
   473 0000023B 803F00                  	cmp	BYTE PTR [bx],0		; see if at null terminator
   474 0000023E 7403                    	je	wql_3				; yes
   475 00000240 43                      	inc	bx
   476 00000241 EBF7                    	jmp	SHORT wql_loop
   477                                  
   478                                  wql_3:
   479 00000243 89C3                    	mov	bx,ax				; bx==file handle, cx==byte count, dx->filename
   480 00000245 B440                    	mov	ah,40h				; write to file
   481 00000247 CD21                    	int	21h
   482 00000249 E8(0000)                    call    restore_ems_map
   483 0000024C 7208                    	jc	wql_doserr			; error occured
   484 0000024E 39C8                    	cmp ax, cx
   485 00000250 B82700                  	mov ax, 27h			; insufficient disk space error
   486 00000253 7501                    	jne wql_doserr
   487 00000255 C3                      	ret
   488                                  
   489                                  wql_doserr:
   490 00000256 E93301                  	jmp	NEAR PTR qlk_doserr
   491                                  
   492                                  write_qlk_libname	ENDP
   493                                  
   494                                  ;*****************************
   495                                  ;* WRITE_QLK_LIB_INFO        *
   496                                  ;*****************************
   497                                  
   498                                  ; write library info to QuickLinker file
   499                                  ; destroys bx,cx,dx
   500                                  
   501                                  write_qlk_lib_info	PROC
   502 00000259 50                      	push	ax				; save critical register
   503 0000025A BA[8000]                	mov	dx,OFFSET qlk_buffer wrt DGROUP
   504 0000025D 8B1E[0200]              	mov	bx,[qlk_handle]
   505                                  
   506                                  ; write lib info byte flag (8)
   507 00000261 C606[8000]08            	mov	byte [qlk_buffer],8
   508 00000266 B90100                  	mov	cx,1
   509 00000269 B440                    	mov	ah,40h				; write to file
   510 0000026B CD21                    	int	21h
   511 0000026D E8(0000)                    call    restore_ems_map
   512 00000270 7222                    	jc	wqi_doserr			; error occured
   513 00000272 39C8                    	cmp ax, cx
   514 00000274 B82700                  	mov ax, 27h			; insufficient disk space error
   515 00000277 751B                    	jne wqi_doserr
   516                                  
   517                                  ; write library page size
   518 00000279 A1[0000]                	mov	ax,[lib_page_size]
   519 0000027C A3[8000]                	mov	WORD PTR [qlk_buffer],ax
   520 0000027F B90200                  	mov	cx,2
   521 00000282 B440                    	mov	ah,40h				; write to file
   522 00000284 CD21                    	int	21h
   523 00000286 E8(0000)                    call    restore_ems_map
   524 00000289 7209                    	jc	wqi_doserr			; error occured
   525 0000028B 39C8                    	cmp ax, cx
   526 0000028D B82700                  	mov ax, 27h			; insufficient disk space error
   527 00000290 7502                    	jne wqi_doserr
   528 00000292 58                      	pop	ax					; restore critical register
   529 00000293 C3                      	ret
   530                                  
   531                                  wqi_doserr:
   532 00000294 E9F500                  	jmp	NEAR PTR qlk_doserr
   533                                  
   534                                  write_qlk_lib_info	ENDP
   535                                  
   536                                  ;*****************************
   537                                  ;* WRITE_QLK_MOD_INFO        *
   538                                  ;*****************************
   539                                  
   540                                  ; write module info to QuickLinker file
   541                                  ; upon entry ax holds module number
   542                                  ; destroys cx,dx
   543                                  
   544                                  write_qlk_mod_info	PROC
   545 00000297 53                      	push	bx
   546 00000298 BA[8000]                	mov	dx,OFFSET qlk_buffer wrt DGROUP
   547 0000029B 8B1E[0400]              	mov	bx,[qlk_buffpos]
   548 0000029F 81FB2501                	cmp	bx,293				; see if at end of buffer
   549 000002A3 7205                    	jb	wqm_2				; no
   550                                  
   551 000002A5 E86400                  	call	flush_qlk_buffer	; flush module info in buffer
   552 000002A8 31DB                    	xor	bx,bx				; re-init buffer position
   553                                  
   554                                  ; write library module flag
   555                                  wqm_2:
   556 000002AA 01D3                    	add	bx,dx				; bx -> start of qlk buffer
   557 000002AC BA2000                  	mov	dx,20h
   558 000002AF 3836[0000]              	cmp	[obj_ovl_flag],dh		; see if overlaid
   559 000002B3 740C                    	je	wqm_4				; no
   560 000002B5 80CA04                  	or	dl,4				; flag overlaid
   561                                  
   562 000002B8 3836[0000]              	cmp	[nonovl_rvect],dh		; see if root vectoring
   563 000002BC 7503                    	jne	wqm_4				; no
   564 000002BE 80CA02                  	or	dl,2				; flag root vectoring
   565                                  
   566                                  wqm_4:
   567 000002C1 3836[0000]              	cmp	[module_flag],dh		; see if module
   568 000002C5 7401                    	je	wqm_5				; no
   569 000002C7 42                      	inc	dx					; flag module (set bit 0 of dl)
   570                                  
   571                                  wqm_5:
   572 000002C8 8817                    	mov	BYTE PTR [bx],dl	; set flag status
   573 000002CA 894701                  	mov	[bx+1],ax
   574 000002CD 8B16[0000]              	mov	dx,[current_lib]
   575 000002D1 895703                  	mov	[bx+3],dx
   576 000002D4 8306[0400]07            	add	word [qlk_buffpos],7		; adjust buffer position
   577 000002D9 5B                      	pop	bx
   578 000002DA C3                      	ret
   579                                  
   580                                  wqm_doserr:
   581 000002DB E9AE00                  	jmp	NEAR PTR qlk_doserr
   582                                  
   583                                  write_qlk_mod_info	ENDP
   584                                  
   585                                  ;*****************************
   586                                  ;* WRITE_QLK_MODSIZE         *
   587                                  ;*****************************
   588                                  
   589                                  ; write library module size or zero if buffer overflow to
   590                                  ; QLK file read/write buffer
   591                                  ; upon entry si+file_pos_adj-lib_pos_adj is size of module
   592                                  ; destroys ax,bx,dx
   593                                  
   594                                  write_qlk_modsize	PROC
   595 000002DE BB[7E00]                	mov	bx,OFFSET qlk_buffer-2 wrt DGROUP
   596 000002E1 031E[0400]              	add	bx,[qlk_buffpos]		; bx -> library module size word slot
   597 000002E5 A1[0000]                	mov	ax,WORD PTR [file_pos_adj]
   598 000002E8 8B16[0200]              	mov	dx,WORD PTR [file_pos_adj+2]
   599 000002EC 2B06[0000]                  sub ax,WORD PTR [lib_pos_adj] ; adjust for library module offset
   600 000002F0 1B16[0200]                  sbb dx,WORD PTR [lib_pos_adj+2]
   601 000002F4 09D0                    	or	ax,dx
   602 000002F6 750E                    	jne	wqm_overflow		; buffer overflowed, use default read
   603 000002F8 89F0                    	mov	ax,si
   604 000002FA 48                      	dec	ax
   605 000002FB 0306[0000]              	add	ax,[lib_page_size]
   606 000002FF 7205                    	jc	wqm_overflow
   607 00000301 24F0                    	and	al,0f0h
   608 00000303 8907                    	mov	[bx],ax
   609 00000305 C3                      	ret
   610                                  
   611                                  ; buffer overflowed reading library module
   612                                  wqm_overflow:
   613 00000306 A1[0000]                	mov	ax,[buffer_end]		; read up to amount in buffer
   614 00000309 8907                    	mov	[bx],ax
   615 0000030B C3                      	ret
   616                                  write_qlk_modsize	ENDP
   617                                  
   618                                  ;*****************************
   619                                  ;* FLUSH_QLK_BUFFER          *
   620                                  ;*****************************
   621                                  
   622                                  ; flush qlk buffer of module info
   623                                  ; upon entry bx == number of bytes to write, dx -> buffer
   624                                  ; destroys bx,cx
   625                                  
   626                                  flush_qlk_buffer	PROC
   627 0000030C 50                      	push	ax				; save module number
   628 0000030D 89D9                    	mov	cx,bx				; get count of bytes to write
   629 0000030F 8B1E[0200]              	mov	bx,[qlk_handle]
   630 00000313 B440                    	mov	ah,40h				; write to file
   631 00000315 CD21                    	int	21h
   632 00000317 E8(0000)                    call    restore_ems_map
   633 0000031A 72BF                    	jc	wqm_doserr			; error occured
   634 0000031C 39C8                    	cmp ax, cx
   635 0000031E B82700                  	mov ax, 27h			; insufficient disk space error
   636 00000321 75B8                    	jne wqm_doserr
   637 00000323 58                      	pop	ax					; restore module number
   638 00000324 C706[0400]0000          	mov	word [qlk_buffpos],0		; init qlk read/write buffer position
   639 0000032A C3                      	ret
   640                                  flush_qlk_buffer	ENDP
   641                                  
   642                                  ;*****************************
   643                                  ;* WRITE_QLK_UNRES           *
   644                                  ;*****************************
   645                                  
   646                                  ; write unresolved externals to the QuickLinker file
   647                                  ; destroys ax,bx,cx,dx
   648                                  
   649                                  write_qlk_unres	PROC
   650 0000032B BA[8000]                	mov	dx,OFFSET qlk_buffer wrt DGROUP
   651 0000032E 8B1E[0400]              	mov	bx,[qlk_buffpos]
   652 00000332 09DB                    	or	bx,bx				; see if pending module info to write
   653 00000334 7403                    	je	wqu_2				; no
   654 00000336 E8D3FF                  	call	flush_qlk_buffer	; flush remaining module info bytes
   655                                  
   656                                  wqu_2:
   657 00000339 8B1E[0200]              	mov	bx,[qlk_handle]
   658                                  
   659                                  ; write unresolved word flag (0FF10h)
   660 0000033D C706[8000]10FF          	mov	WORD [qlk_buffer],0ff10h
   661 00000343 B90200                  	mov	cx,2
   662 00000346 B440                    	mov	ah,40h				; write to file
   663 00000348 CD21                    	int	21h
   664 0000034A E8(0000)                    call    restore_ems_map
   665 0000034D 723D                    	jc	qlk_doserr			; error occured
   666 0000034F 39C8                    	cmp ax, cx
   667 00000351 B82700                  	mov ax, 27h			; insufficient disk space error
   668 00000354 7536                    	jne qlk_doserr
   669                                  
   670                                  ; write count of unresolved externals
   671 00000356 A1[0000]                	mov	ax,WORD PTR [tot_sym_count]
   672 00000359 2B06[0000]              	sub	ax,WORD PTR [pub_sym_count]
   673 0000035D A3[8000]                	mov	WORD PTR [qlk_buffer],ax
   674 00000360 B90200                  	mov	cx,2
   675 00000363 B440                    	mov	ah,40h				; write to file
   676 00000365 CD21                    	int	21h
   677 00000367 E8(0000)                    call    restore_ems_map
   678 0000036A 7220                    	jc	qlk_doserr			; error occured
   679 0000036C 39C8                    	cmp ax, cx
   680 0000036E B82700                  	mov ax, 27h			; insufficient disk space error
   681 00000371 7519                    	jne qlk_doserr
   682                                  
   683                                  ; write end byte flag (80h)
   684 00000373 C606[8000]80            	mov	byte [qlk_buffer],80h
   685 00000378 B90100                  	mov	cx,1
   686 0000037B B440                    	mov	ah,40h				; write to file
   687 0000037D CD21                    	int	21h
   688 0000037F E8(0000)                    call    restore_ems_map
   689 00000382 7208                    	jc	qlk_doserr			; error occured
   690 00000384 39C8                    	cmp ax, cx
   691 00000386 B82700                  	mov ax, 27h			; insufficient disk space error
   692 00000389 7501                    	jne qlk_doserr
   693 0000038B C3                      	ret
   694                                  
   695                                  qlk_doserr:
   696 0000038C BA[0000]                	mov	dx,OFFSET filename wrt DGROUP
   697 0000038F E9(0000)                    jmp NEAR PTR dos_error	; dos error
   698                                  
   699                                  write_qlk_unres	ENDP
   700                                  
   701                                  ;*****************************
   702                                  ;* DELETE_QLK_FILE           *
   703                                  ;*****************************
   704                                  
   705                                  ; close and delete the qlk file if it exists and writing to it
   706                                  ; destroys ax,bx,cx,dx
   707                                  
   708                                  delete_qlk_file PROC
   709 00000392 803E[0000]00            	cmp	byte [writing_qlk_flag],0	; see if writing to qlk file
   710 00000397 741B                    	je	dqf_ret				; no, reading, okay to keep
   711                                  
   712 00000399 8B1E[0200]                  mov bx,[qlk_handle]
   713 0000039D 09DB                        or  bx,bx               ; see if file exists
   714 0000039F 7413                        je  dqf_ret             ; no
   715 000003A1 B43E                        mov ah,3eh              ; close file
   716 000003A3 CD21                        int 21h
   717 000003A5 E8(0000)                    call    restore_ems_map
   718                                  
   719 000003A8 BA[0000]                    mov dx,OFFSET qlk_name wrt DGROUP
   720 000003AB B441                        mov ah,41h              ; delete file
   721 000003AD CD21                        int 21h
   722 000003AF 31C0                        xor ax,ax               ; zero out file handle so no further deletion attempts
   723 000003B1 A3[0200]                    mov [qlk_handle],ax
   724                                  
   725                                  dqf_ret:
   726 000003B4 C3                          ret
   727                                  delete_qlk_file ENDP
   728                                  
   729                                  END
