     1                                  ;*********************************************************************
     2                                  ;*   MLERROR.ASM                                                     *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          12/31/92                                         *
     6                                  ;*   Model:         Small                                            *
     7                                  ;*   Version:       2.5                                              *
     8                                  ;*   Assembler:     MASM 5.0                                         *
     9                                  ;*   Environment:   MS-DOS 2.x+                                      *
    10                                  ;*                                                                   *
    11                                  ;*   give linker error/warning message and terminate if fatal        *
    12                                  ;*                                                                   *
    13                                  ;*********************************************************************
    14                                  
    15                                  ;TITLE   WARPLINK mlerror
    16                                  ;PAGE    50,80
    17                                  
    18                                  ;.MODEL  SMALL
    19                                  
    20                                  ;*****************************
    21                                  ;* Equates                   *
    22                                  ;*****************************
    23                                  
    24                                  %define ALLOCATE_ERROR_DATA 1   ; allocate data space for error messages
    25                                  
    26                                  ;*****************************
    27                                  ;* Include files             *
    28                                  ;*****************************
    29                                  
    30                                  [list -]
    14                              <2> [list -]
    14                              <1> [list -]
    32                                  [list -]
    37                                  
    38                                  ;*****************************
    39                                  ;* Public declarations       *
    40                                  ;*****************************
    41                                  
    42                                  PUBLIC  link_error,dos_error,link_warning,give_warn_count,fixup_warning
    43                                  PUBLIC  check_xms_error
    44                                  
    45                                  ;*****************************
    46                                  ;* External declarations     *
    47                                  ;*****************************
    48                                  
    49                                  EXTRN   filename:BYTE,temp_file_name:BYTE
    50                                  EXTRN   frame_method:BYTE,target_method:BYTE,target_disp:DWORD
    51                                  EXTRN   frext_ingroup:BYTE
    52                                  EXTRN   frame_ent_ptr:WORD,targ_ent_ptr:WORD
    53                                  
    54                                  ;*****************************
    55                                  ;* Data begins               *
    56                                  ;*****************************
    57                                  
    58                                  .DATA
    59                                  
    60                                  ; initialized local variables
    61                                  
    62                                  ; byte values
    63                                  ; 'cascade_' flags prevents cascading warning solutions for same problem
    64 00000000 00                      cascade_unresolved  DB  0
    65 00000001 00                      cascade_multsym DB  0
    66 00000002 00                      cascade_fixup   DB  0
    67 00000003 00                      cascade_segdecl DB  0
    68 00000004 00                      cascade_nonovlseg   DB  0
    69 00000005 00                      cascade_nonovlsym   DB  0
    70 00000006 00                      cascade_wlcalc_wllist:		db 0
    71                                  
    72                                  .DATA?
    73                                  
    74                                  ; uninitialized local variables
    75                                  ; byte values
    76 00000000 ??                      error_type  DB  ?           ; type of error
    77 00000001 ??                      warn_type   DB  ?           ; type of warning
    78                                  
    79                                  ; word values
    80                                  temp_flag   LABEL   WORD    ; used by link_warning to fake out print_lib_mod, share space with link_error
    80                              <1> temp_flag :
    81 00000002 ????                    error_value DW  ?           ; 8 or 16 bit value of file error, if any
    82                                  
    83                                  ; byte string values
    84 00000004 <res Ch>                number_hex  DB  12 DUP (?)  ; room for doubleword max value plus 'h' suffix and '0' prefix
    85 00000010 ??????????              number_buff DB  5 DUP (?)   ; temporary buffer for decimal ASCII value (reversed)
    86                                  
    87                                  ;*****************************
    88                                  ;* Constant data             *
    89                                  ;*****************************
    90                                  
    91                                  .CONST
    92                                  
    93 00003246 1E                      warn_tlen   DB  warn_tstop-warn_text
    94 00003247 0D0A0D0A546F74616C-     warn_text   DB  CR,LF,CR,LF,'Total number of warnings: '
    94 00003250 206E756D626572206F-
    94 00003259 66207761726E696E67-
    94 00003262 733A20             
    95                                  warn_tstop  equ   $
    96                                  
    97 00003265 0D0A20204672616D65-     fw_frame_text   DB  CR,LF,'  Frame '
    97 0000326E 20                 
    98 0000326F 0D0A20205461726765-     fw_targ_text    DB  CR,LF,'  Target '
    98 00003278 7420               
    99 0000327A 7365676D656E7420        fw_seg_text     DB  'segment '
   100 00003282 67726F757020            fw_group_text   DB  'group '
   101 00003288 4C4F434154494F4E        fw_loc_text     DB  'LOCATION'
   102 00003290 73796D626F6C20          fw_sym_text     DB  'symbol '
   103 00003297 2C20646973706C6163-     fw_disp_text    DB  ', displacement '
   103 000032A0 656D656E7420       
   104                                  
   105                                  ;*****************************
   106                                  ;* Code begins               *
   107                                  ;*****************************
   108                                  
   109                                  .CODE
   110                                  
   111                                  ;*****************************
   112                                  ;* External declarations     *
   113                                  ;*****************************
   114                                  
   115                                  EXTRN   exit_link:NEAR
   116                                  EXTRN   restore_ems_map:NEAR,delete_ilf_file:NEAR
   117                                  EXTRN	delete_temp_file:NEAR,delete_qlk_file:NEAR
   118                                  
   119                                  ;*****************************
   120                                  ;* LINK_ERROR                *
   121                                  ;*****************************
   122                                  
   123                                  ; print fatal error feedback
   124                                  ; ax has error code upon entry
   125                                  ; dx -> filename with error, if any
   126                                  ; cx == value of error, if any (-> symbol name for communal overflow error)
   127                                  ;   (-> start of bad option if bad option)
   128                                  
   129                                  link_error  PROC
   130 00000000 BB[ssss]                    mov bx,DGROUP
   131 00000003 8EDB                        mov ds,bx               ; point data segment at WarpLink's data
   132 00000005 83F86D                      cmp ax,HIGH_ERR_CODE    ; make sure error code isn't out of bounds
   133 00000008 7606                        jbe le_code_okay        ; not out of bounds
   134                                  
   135 0000000A B80000                      mov ax,INTERNAL_ERR     ; force error as internal error
   136 0000000D B9FF00                      mov cx,255              ; 255 internal error value
   137                                  
   138                                  le_code_okay:
   139 00000010 890E[0200]                  mov [error_value],cx
   140 00000014 A2[0000]                    mov [error_type],al       ; save type of error
   141                                  
   142 00000017 BB[0000]                    mov bx,OFFSET error_table_start wrt DGROUP  ; point to start of error message address table
   143                                  ; adjust ax for offset in table by multiplying by 8 (4 word values each entry)
   144 0000001A D1E0                        shl ax,1                ; x2
   145 0000001C D1E0                        shl ax,1                ; x4
   146 0000001E D1E0                        shl ax,1                ; x8
   147 00000020 01C3                        add bx,ax               ; bx -> proper entry in table
   148 00000022 89DF                        mov di,bx               ; save offset in table
   149                                  
   150 00000024 8B07                        mov ax,[bx]             ; get error type flags
   151 00000026 A92000                      test    ax,DOS_ERRVAL   ; see if a DOS error
   152 00000029 7412                        je  le_nondos           ; no
   153 0000002B 83E006                      and ax,6                ; get unknown/internal/command line/file type
   154 0000002E 83F806                      cmp ax,6                ; see if DOS file error
   155 00000031 7505                        jne le_1                ; no
   156 00000033 BB[4304]                    mov bx,OFFSET sttyp_fatal_dosmod wrt DGROUP ; DOS file error
   157 00000036 EB35                        jmp SHORT print_first   ; print first part of feedback
   158                                  
   159                                  le_1:
   160 00000038 BB[3104]                    mov bx,OFFSET sttyp_fatal_dos wrt DGROUP    ; DOS nonfile error
   161 0000003B EB30                        jmp SHORT print_first   ; print first part of feedback
   162                                  
   163                                  le_nondos:
   164 0000003D 89C3                        mov bx,ax               ; save error type flag value
   165 0000003F 83E006                      and ax,6                ; get unknown:unspecified/internal/command line/file type
   166 00000042 7514                        jne le_2                ; not unknown/unspecified type
   167 00000044 83E340                      and bx,NOSPEC_ERRVAL    ; get unspecified bit
   168 00000047 7405                        je  le_unknown          ; not set, unknown
   169 00000049 BB[FE03]                    mov bx,OFFSET sttyp_fatal_error wrt DGROUP
   170 0000004C EB1F                        jmp SHORT print_first   ; print first part of feedback
   171                                  
   172                                  le_unknown:
   173 0000004E F60580                  	testopt [di], EXTRA_SYM_ERRVAL
   174 00000051 7517                    	jnz le4_extra
   175                                  
   176 00000053 BB[E803]                    mov bx,OFFSET sttyp_fatal_unknown wrt DGROUP
   177 00000056 EB15                        jmp SHORT print_first   ; print first part of feedback
   178                                  
   179                                  le_2:
   180 00000058 3C02                        cmp al,INTERNAL_ERRVAL
   181 0000005A 7505                        jne le_3                ; no internal type
   182 0000005C BB[9E03]                    mov bx,OFFSET sttyp_fatal_internal wrt DGROUP
   183 0000005F EB0C                        jmp SHORT print_first   ; print first part of feedback
   184                                  
   185                                  le_3:
   186 00000061 3C04                        cmp al,COMMAND_ERRVAL
   187 00000063 7505                        jne le_4                ; no command line/user type
   188 00000065 BB[C103]                    mov bx,OFFSET sttyp_fatal_comline wrt DGROUP
   189 00000068 EB03                        jmp SHORT print_first   ; print first part of feedback
   190                                  
   191                                  le4_extra:
   192                                  ; error in file
   193                                  le_4:
   194 0000006A BB[0C04]                    mov bx,OFFSET sttyp_fatal_objmod wrt DGROUP
   195                                  
   196                                  print_first:
   197 0000006D 52                          push    dx              ; save dx -> filename for file errors
   198 0000006E 8A4FFF                      mov cl,[bx-1]           ; get length of string
   199 00000071 89DA                        mov dx,bx               ; ds:dx -> string
   200 00000073 30ED                        xor ch,ch               ; zap high byte of cx
   201 00000075 BB0100                      mov bx,STDOUT           ; write to standard output device
   202 00000078 B440                        mov ah,40h              ; write to device
   203 0000007A CD21                        int 21h
   204                                  %IFNDEF JUNIOR
   205 0000007C E8(0000)                    call    restore_ems_map
   206                                  %ENDIF
   207                                  
   208 0000007F 5A                          pop dx                  ; restore dx -> filename for file errors
   209 00000080 8B05                        mov ax,[di]             ; get error type flags
   210 00000082 2406                        and al,6
   211 00000084 3C02                        cmp al,INTERNAL_ERRVAL  ; see if internal error
   212 00000086 7503                        jne le_5                ; no
   213 00000088 E9A900                      jmp NEAR PTR pf_value   ; yes, print value of internal error
   214                                  
   215                                  le_5:
   216 0000008B 3C06                        cmp al,FILE_ERRVAL      ; see if file type error
   217 0000008D 7423                        je  pf_file_err         ; yes
   218 0000008F 803E[0000]05                cmp byte [error_type],BAD_OPTION_ERR   ; see if bad option error
   219 00000094 7408                        je  pf_bad_option       ; yes
   220 00000096 F60580                  	testopt [di], EXTRA_SYM_ERRVAL
   221 00000099 755A                    	jnz le_extra
   222                                  ;***    jmp NEAR PTR pf_colon   ; no
   223 0000009B E98A00                      jmp pf_4          ; no
   224                                  
   225                                  ; bad option error
   226                                  pf_bad_option:
   227 0000009E BA[8904]                    mov dx,OFFSET sttyp_option wrt DGROUP   ; print ', option /' string
   228 000000A1 B90A00                      mov cx,10
   229 000000A4 BB0100                      mov bx,STDOUT           ; write to standard output
   230 000000A7 B440                        mov ah,40h              ; write to device
   231 000000A9 CD21                        int 21h
   232                                  %IFNDEF JUNIOR
   233 000000AB E8(0000)                    call    restore_ems_map
   234                                  %ENDIF
   235                                  
   236                                  ; print the bad option
   237 000000AE 8B16[0200]                  mov dx,[error_value]      ; ds:dx -> bad option string
   238                                  
   239                                  pf_file_err:
   240 000000B2 89D3                        mov bx,dx
   241 000000B4 31C9                        xor cx,cx               ; cx will contain number of chars in file name
   242                                  ploop1:
   243 000000B6 803F20                      cmp BYTE PTR [bx],' '   ; see if white space/terminator in file name found
   244 000000B9 7604                        jbe pf_2                ; yes
   245 000000BB 41                          inc cx                  ; bump count of chars in string
   246 000000BC 43                          inc bx                  ; move to next char slot to test
   247 000000BD EBF7                        jmp SHORT ploop1        ; loop back to test next char
   248                                  
   249                                  ; write the file name/bad option
   250                                  pf_2:
   251 000000BF BB0100                      mov bx,STDOUT           ; write to standard output device
   252 000000C2 B440                        mov ah,40h              ; write to device
   253 000000C4 CD21                        int 21h
   254                                  %IFNDEF JUNIOR
   255 000000C6 E8(0000)                    call    restore_ems_map
   256                                  %ENDIF
   257                                  
   258 000000C9 803E[0000]05                cmp byte [error_type],BAD_OPTION_ERR   ; see if bad option error
   259 000000CE 747B                        je  pf_colon            ; yes
   260                                  
   261 000000D0 8B05                        mov ax,[di]             ; get flags
   262 000000D2 2418                        and al,NO_OFF_ERRVAL    ; get offset/value bit field
   263 000000D4 3C18                        cmp al,NO_OFF_ERRVAL    ; see if no file offset for error
   264 000000D6 7403                        je pf_3                 ; no offset
   265 000000D8 E87D02                      call    print_offset    ; print 'offset' string and file error offset in hex
   266                                  
   267                                  pf_3:
   268 000000DB E81202                      call    print_lib_mod   ; check if processing library, print module name/offset if so
   269                                  
   270 000000DE 803E[0000]4B                cmp byte [error_type], _WLCALC_WLLIST_MINIMUM
   271 000000E3 7207                        jb .check_comm
   272 000000E5 803E[0000]6A                cmp byte [error_type], _WLCALC_WLLIST_MAXIMUM
   273 000000EA 7607                        jbe @F
   274                                  .check_comm:
   275 000000EC 803E[0000]38                cmp byte [error_type],COMM_OVRFLW_ERR  ; see if communal symbol name should be printed
   276 000000F1 7535                        jne pf_4                ; no
   277                                  @@:
   278 000000F3 EB08                    	jmp @F
   279                                  
   280                                  le_extra:
   281 000000F5 BA[7704]                    mov dx,OFFSET sttyp_symbol + 2 wrt DGROUP
   282 000000F8 B90700                      mov cx,7
   283 000000FB EB06                        jmp @FF
   284                                  @@:
   285                                  ; print ", symbol "
   286 000000FD BA[7504]                    mov dx,OFFSET sttyp_symbol wrt DGROUP
   287 00000100 B90900                      mov cx,9                ; nine chars in string
   288                                  @@:
   289 00000103 BB0100                      mov bx,STDOUT           ; write to standard output device
   290 00000106 B440                        mov ah,40h              ; write to device
   291 00000108 CD21                        int 21h
   292                                  %IFNDEF JUNIOR
   293 0000010A E8(0000)                    call    restore_ems_map
   294                                  %ENDIF
   295                                  
   296                                  ; get number of chars in symbol name
   297 0000010D 8B16[0200]                  mov dx,[error_value]      ; get -> symbol name
   298 00000111 89D3                        mov bx,dx               ; ds:dx -> symbol name
   299 00000113 31C9                        xor cx,cx               ; cx will contain number of chars in sumbol name
   300                                  ploop2:
   301 00000115 803F00                      cmp BYTE PTR [bx],0     ; see if zero terminator in symbol name found
   302 00000118 7404                        je  pf_3a               ; yes
   303 0000011A 41                          inc cx                  ; bump count of chars in string
   304 0000011B 43                          inc bx                  ; move to next char slot to test
   305 0000011C EBF7                        jmp SHORT ploop2        ; loop back to test next char
   306                                  
   307                                  ; write the symbol name
   308                                  pf_3a:
   309 0000011E BB0100                      mov bx,STDOUT           ; write to standard output device
   310 00000121 B440                        mov ah,40h              ; write to device
   311 00000123 CD21                        int 21h
   312                                  %IFNDEF JUNIOR
   313 00000125 E8(0000)                    call    restore_ems_map
   314                                  %ENDIF
   315                                  
   316                                  ; check if value
   317                                  pf_4:
   318 00000128 8B05                        mov ax,[di]             ; get flags
   319 0000012A 2418                        and al,NO_OFF_ERRVAL    ; get offset/value bit field
   320 0000012C 3C18                        cmp al,NO_OFF_ERRVAL    ; see if no value error
   321 0000012E 741B                        je pf_colon             ; no value
   322 00000130 08C0                        or  al,al
   323 00000132 7417                        je  pf_colon            ; no value, finish up line with colon
   324                                  
   325                                  ; print 'value' string
   326                                  pf_value:
   327 00000134 BB[2804]                    mov bx,OFFSET sttyp_value wrt DGROUP
   328 00000137 8A4FFF                      mov cl,[bx-1]           ; get length of string
   329 0000013A 89DA                        mov dx,bx               ; ds:dx -> string
   330 0000013C 30ED                        xor ch,ch               ; zap high byte of cx
   331 0000013E BB0100                      mov bx,STDOUT           ; write to standard output device
   332 00000141 B440                        mov ah,40h              ; write to device
   333 00000143 CD21                        int 21h
   334                                  %IFNDEF JUNIOR
   335 00000145 E8(0000)                    call    restore_ems_map
   336                                  %ENDIF
   337                                  
   338 00000148 E87F02                      call    print_value     ; print error value in hex
   339                                  
   340                                  ; print a colon after the file error message
   341                                  pf_colon:
   342 0000014B BA[5804]                    mov dx,OFFSET sttyp_colon wrt DGROUP
   343 0000014E B90100                      mov cx,1                ; one char to write
   344 00000151 BB0100                      mov bx,STDOUT           ; write to standard output device
   345 00000154 B440                        mov ah,40h              ; write to device
   346 00000156 CD21                        int 21h
   347                                  %IFNDEF JUNIOR
   348 00000158 E8(0000)                    call    restore_ems_map
   349                                  %ENDIF
   350                                  
   351                                  pf_print_ps:
   352 0000015B E8D802                      call    print_problem   ; print problem
   353 0000015E E8FD02                      call    print_solution  ; print solution
   354                                  
   355                                  ; delete ilf file if it exists
   356 00000161 E8(0000)                    call    delete_ilf_file
   357 00000164 E8(0000)                	call	delete_temp_file	; delete temp file if exists
   358                                   extern delete_wllist_temps
   359 00000167 B001                    	mov al, 1			; display linebreak
   360 00000169 E8(0000)                	call delete_wllist_temps
   361 0000016C E8(0000)                	call	delete_qlk_file	; kill qlk file too, if writing to it
   362                                  
   363                                  pf_chkovl:
   364 0000016F 803E[0000]00                cmp byte [is_internal],0       ; check if temporary overlay file
   365 00000174 7419                        je  pf_out              ; no
   366                                  
   367                                  ; delete temporary overlay file if exists
   368 00000176 8B1E[0000]                  mov bx,[ovl_handle]       ; get overlay file handle
   369 0000017A 09DB                        or  bx,bx               ; make sure not zero
   370 0000017C 7411                        je  pf_out              ; zero, no overlay file to delete
   371 0000017E B43E                        mov ah,3eh              ; close file
   372 00000180 CD21                        int 21h
   373                                  %IFNDEF JUNIOR
   374 00000182 E8(0000)                    call    restore_ems_map
   375                                  %ENDIF
   376 00000185 BA[0000]                    mov dx,OFFSET ovl_filename wrt DGROUP
   377 00000188 B441                        mov ah,41h              ; delete file
   378 0000018A CD21                        int 21h
   379                                  %IFNDEF JUNIOR
   380 0000018C E8(0000)                    call    restore_ems_map
   381                                  %ENDIF
   382                                  
   383                                  pf_out:
   384 0000018F A0[0000]                    mov al,[error_type]
   385 00000192 0402                        add al,2
   386 00000194 E9(0000)                    jmp NEAR PTR exit_link  ; terminate with return code of error+2
   387                                  link_error  ENDP
   388                                  
   389                                  ;*****************************
   390                                  ;* LINK_WARNING              *
   391                                  ;*****************************
   392                                  
   393                                  ; print warning message feedback
   394                                  ; ax has error code upon entry
   395                                  ; ds:dx -> primary string associated with warning message,
   396                                  ; es:di -> secondary string associated with warning message, if any
   397                                  
   398                                  link_warning    PROC
   399 00000197 1E                          push    ds              ; save all used registers
   400 00000198 56                          push    si
   401 00000199 57                          push    di
   402 0000019A 52                          push    dx
   403 0000019B 51                          push    cx
   404 0000019C 53                          push    bx
   405 0000019D 50                          push    ax              ; save error code, ax is used
   406 0000019E BB[ssss]                    mov bx,DGROUP           ; get address of dgroup
   407 000001A1 8EDB                        mov ds,bx               ; point data segment at Machlink's data
   408 000001A3 A2[0100]                    mov [warn_type],al        ; save type of warning
   409 000001A6 803E[0000]00                cmp byte [is_nowarn],0         ; see if warnings disabled
   410 000001AB 7403                        je  lw_1                ; no
   411                                  lw_ret_j:
   412 000001AD E93401                      jmp lw_ret     ; yes
   413                                  
   414                                  lw_1:
   415 000001B0 83F82C                  	cmp ax, NO_EXE_STACK_WARN
   416 000001B3 7507                    	jne .notstack
   417 000001B5 803E[0000]00            	cmp byte [is_stack_nowarn], 0
   418 000001BA 75F1                    	jne lw_ret_j
   419                                  .notstack:
   420                                  
   421 000001BC BB[0000]                    mov bx,OFFSET error_table_start wrt DGROUP  ; point to start of error message address table
   422                                  ; adjust ax for offset in table by multiplying by 8 (4 word values each entry)
   423 000001BF D1E0                        shl ax,1                ; x2
   424 000001C1 D1E0                        shl ax,1                ; x4
   425 000001C3 D1E0                        shl ax,1                ; x8
   426 000001C5 01C3                        add bx,ax               ; bx -> proper entry in table
   427 000001C7 53                          push    bx              ; save pointer to entry
   428 000001C8 52                          push    dx              ; save pointer to primary string
   429                                  
   430                                  ; print 'Warning in ' string
   431 000001C9 BB[5C04]                    mov bx,OFFSET sttyp_warning wrt DGROUP
   432 000001CC 8A4FFF                      mov cl,[bx-1]           ; get length of string
   433 000001CF 89DA                        mov dx,bx               ; ds:dx -> string
   434 000001D1 30ED                        xor ch,ch               ; zap high byte of cx
   435 000001D3 BB0100                      mov bx,STDOUT           ; write to standard output device
   436 000001D6 B440                        mov ah,40h              ; write to device
   437 000001D8 CD21                        int 21h
   438                                  %IFNDEF JUNIOR
   439 000001DA E8(0000)                    call    restore_ems_map
   440                                  %ENDIF
   441                                  
   442 000001DD 5A                          pop dx                  ; restore pointer to primary warning string
   443 000001DE 31C9                        xor cx,cx               ; cx will contain number of chars in file name
   444 000001E0 89D3                        mov bx,dx
   445                                  wloop1:
   446 000001E2 803F00                      cmp BYTE PTR [bx],0     ; see if zero terminator in file name found
   447 000001E5 7404                        je  lw_2                ; yes
   448 000001E7 41                          inc cx                  ; bump count of chars in string
   449 000001E8 43                          inc bx                  ; move to next char slot to test
   450 000001E9 EBF7                        jmp SHORT wloop1        ; loop back to test next char
   451                                  
   452                                  ; write primary warning string
   453                                  lw_2:
   454 000001EB BB0100                      mov bx,STDOUT           ; write to standard output device
   455 000001EE B440                        mov ah,40h              ; write to device
   456 000001F0 CD21                        int 21h
   457                                  %IFNDEF JUNIOR
   458 000001F2 E8(0000)                    call    restore_ems_map
   459                                  %ENDIF
   460                                  
   461 000001F5 A0[0100]                    mov al,[warn_type]
   462 000001F8 3C6D                    	cmp al, MULTIPLE_ENTRYPOINT_WARN
   463 000001FA 7408                    	je @F
   464 000001FC 3C6B                    	cmp al, COM_PREFIX_UNKNOWN_WARN
   465 000001FE 7404                    	je @F
   466 00000200 3C2C                        cmp al,NO_EXE_STACK_WARN    ; see if secondary string used
   467 00000202 7505                        jne lw_secondary        ; yes
   468                                  @@:
   469                                  
   470                                  ; no secondary string used
   471 00000204 E8E900                      call    print_lib_mod   ; check if processing library, print module name is so
   472 00000207 EB72                        jmp SHORT lw_3          ; bypass secondary string code
   473                                  
   474                                  ; see if file offset used
   475                                  lw_secondary:
   476 00000209 3C30                        cmp al,SEG_GRP_DECL_WARN
   477 0000020B 7408                        je  lw_offset
   478 0000020D 3C43                        cmp al,NONOVL_SEG_WARN
   479 0000020F 7404                        je  lw_offset
   480 00000211 3C44                        cmp al,NONOVL_SYM_WARN
   481 00000213 7507                        jne lw_no_offset        ; no offset
   482                                  
   483                                  ; print offset string and hex value
   484                                  lw_offset:
   485 00000215 E84001                      call    print_offset
   486 00000218 31C0                        xor ax,ax               ; fake out print_lib_mod to print offset
   487 0000021A EB02                        jmp SHORT lw_shared     ; jump to code shared with no print offset routine
   488                                  
   489                                  lw_no_offset:
   490 0000021C B018                        mov al,NO_OFF_ERRVAL        ; fake out print_lib_mod NOT to print offset
   491                                  
   492                                  lw_shared:
   493 0000021E A3[0200]                    mov [temp_flag],ax
   494 00000221 57                          push    di              ; save critical register
   495 00000222 BF[0200]                    mov di,OFFSET temp_flag wrt DGROUP
   496 00000225 E8C800                      call    print_lib_mod   ; check if processing library, print module name if so
   497 00000228 5F                          pop di                  ; restore critical register
   498                                  
   499                                  lw_2a:
   500 00000229 A0[0100]                    mov al,[warn_type]
   501 0000022C 3C4B                        cmp al, _WLCALC_WLLIST_MINIMUM
   502 0000022E 7204                        jb @F
   503 00000230 3C6A                        cmp al, _WLCALC_WLLIST_MAXIMUM
   504 00000232 7611                        jbe lw_symbol
   505                                  @@:
   506 00000234 3C2D                        cmp al,UNRES_EXT_WARN   ; see if symbol name printed
   507 00000236 740D                        je  lw_symbol           ; yes
   508 00000238 3C2E                        cmp al,MULT_DEF_SYM_WARN    ; see if symbol name printed
   509 0000023A 7409                        je  lw_symbol           ; print symbol name
   510 0000023C 3C44                        cmp al,NONOVL_SYM_WARN
   511 0000023E 7405                        je  lw_symbol           ; yes
   512                                  
   513                                  ; print segment
   514                                  lw_segment:
   515 00000240 BB[6A04]                    mov bx,OFFSET sttyp_segment wrt DGROUP
   516 00000243 EB03                        jmp SHORT lw_printss
   517                                  
   518                                  ; print symbol
   519                                  lw_symbol:
   520 00000245 BB[7504]                    mov bx,OFFSET sttyp_symbol wrt DGROUP
   521                                  
   522                                  ; print 'segment' or 'symbol' string
   523                                  lw_printss:
   524 00000248 8A4FFF                      mov cl,[bx-1]           ; get length of string
   525 0000024B 30ED                        xor ch,ch               ; zap high byte of cx
   526 0000024D 89DA                        mov dx,bx               ; ds:dx -> string
   527 0000024F BB0100                      mov bx,STDOUT           ; write to standard output device
   528 00000252 B440                        mov ah,40h              ; write to device
   529 00000254 CD21                        int 21h
   530                                  %IFNDEF JUNIOR
   531 00000256 E8(0000)                    call    restore_ems_map
   532                                  %ENDIF
   533                                  
   534                                  ; get length of segment/symbol name
   535 00000259 89FB                        mov bx,di
   536 0000025B 31C9                        xor cx,cx               ; cx will contain number of chars in segment name
   537 0000025D 8CC0                        mov ax,es
   538 0000025F 8ED8                        mov ds,ax               ; ds:bx -> segment/symbol name
   539                                  
   540                                  wloop2:
   541 00000261 803F00                      cmp BYTE PTR [bx],0     ; see if zero terminator in file name found
   542 00000264 7404                        je  print_segsym        ; yes
   543 00000266 41                          inc cx                  ; bump count of chars in string
   544 00000267 43                          inc bx                  ; move to next char slot to test
   545 00000268 EBF7                        jmp SHORT wloop2        ; loop back to test next char
   546                                  
   547                                  ; print name of segment/symbol from es:di
   548                                  print_segsym:
   549 0000026A 89FA                        mov dx,di               ; ds:dx -> string to print
   550 0000026C BB0100                      mov bx,STDOUT           ; write to standard output device
   551 0000026F B440                        mov ah,40h              ; write to device
   552 00000271 CD21                        int 21h
   553                                  %IFNDEF JUNIOR
   554 00000273 E8(0000)                    call    restore_ems_map
   555                                  %ENDIF
   556                                  
   557 00000276 B8[ssss]                    mov ax,DGROUP
   558 00000279 8ED8                        mov ds,ax               ; restore ds -> warplink data
   559                                  
   560                                  lw_3:
   561 0000027B 5B                          pop bx                  ; restore pointer to entry
   562 0000027C 89DF                        mov di,bx               ; save it in di
   563 0000027E E8B501                      call    print_problem   ; print problem
   564                                  
   565 00000281 A0[0100]                    mov al,[warn_type]        ; get type of warning
   566 00000284 3A06[0000]                  cmp al,[cascade_unresolved]   ; see if problem/solution already printed once
   567 00000288 745A                        je  lw_ret              ; yes
   568 0000028A 3C2D                        cmp al,UNRES_EXT_WARN   ; see if unresolved external type
   569 0000028C 7505                        jne lw_4                ; no
   570 0000028E A2[0000]                    mov [cascade_unresolved],al   ; flag that problem/solution was printed
   571 00000291 EB4E                        jmp SHORT lw_print_sol  ; skip other code
   572                                  
   573                                  ; check other cascade flags
   574                                  lw_4:
   575 00000293 3A06[0100]                  cmp al,[cascade_multsym] 
   576 00000297 744B                        je  lw_ret
   577 00000299 3C2E                        cmp al,MULT_DEF_SYM_WARN    ; see if multiply defined symbol
   578 0000029B 7505                        jne lw_5                ; no
   579 0000029D A2[0100]                    mov [cascade_multsym],al  ; flag that problem/solution was printed
   580 000002A0 EB3F                        jmp SHORT lw_print_sol  ; skip other code
   581                                  
   582                                  lw_5:
   583 000002A2 3A06[0300]                  cmp al,[cascade_segdecl]
   584 000002A6 743C                        je  lw_ret
   585 000002A8 3C30                        cmp al,SEG_GRP_DECL_WARN    ; see if segment declared in more than one group
   586 000002AA 7505                        jne lw_6                ; no
   587 000002AC A2[0300]                    mov [cascade_segdecl],al  ; flag that problem/solution was printed
   588 000002AF EB30                        jmp SHORT lw_print_sol  ; skip other code
   589                                  
   590                                  lw_6:
   591 000002B1 3A06[0400]                  cmp al,[cascade_nonovlseg]
   592 000002B5 742D                        je  lw_ret
   593 000002B7 3C43                        cmp al,NONOVL_SEG_WARN  ; see if nonoverlayble segment ref warning
   594 000002B9 7505                        jne lw_7                ; no
   595 000002BB A2[0400]                    mov [cascade_nonovlseg],al    ; flag that problem/solution was printed
   596 000002BE EB21                        jmp SHORT lw_print_sol  ; skip other code
   597                                  
   598                                  lw_7:
   599 000002C0 3A06[0500]                  cmp al,[cascade_nonovlsym]
   600 000002C4 741E                        je  lw_ret
   601 000002C6 3C44                        cmp al,NONOVL_SYM_WARN  ; see if nonoverlayble segment ref warning
   602 000002C8 7505                        jne lw_8                ; no
   603 000002CA A2[0500]                    mov [cascade_nonovlsym],al    ; flag that problem/solution was printed
   604 000002CD EB12                        jmp SHORT lw_print_sol  ; skip other code
   605                                  
   606                                  lw_8:
   607 000002CF 3C4B                    	cmp al, _WLCALC_WLLIST_MINIMUM
   608 000002D1 720E                    	jb @F
   609 000002D3 3C6A                    	cmp al, _WLCALC_WLLIST_MAXIMUM
   610 000002D5 770A                    	ja @F
   611 000002D7 D006[0600]              	rol byte [cascade_wlcalc_wllist], 1
   612 000002DB 7207                    	jc lw_ret
   613 000002DD F616[0600]              	not byte [cascade_wlcalc_wllist]
   614                                  @@:
   615                                  
   616                                  ; room for more warning cascade checks
   617                                  
   618                                  lw_print_sol:
   619 000002E1 E87A01                      call    print_solution  ; print solution
   620                                  
   621                                  lw_ret:
   622 000002E4 FF06[0000]                  inc word [warn_count]          ; bump count of warning messages
   623 000002E8 58                          pop ax                  ; restore registers
   624 000002E9 5B                          pop bx
   625 000002EA 59                          pop cx
   626 000002EB 5A                          pop dx
   627 000002EC 5F                          pop di
   628 000002ED 5E                          pop si
   629 000002EE 1F                          pop ds
   630 000002EF C3                          ret
   631                                  link_warning    ENDP
   632                                  
   633                                  ;*****************************
   634                                  ;* PRINT_LIB_MOD             *
   635                                  ;*****************************
   636                                  
   637                                  ; print library module string and name
   638                                  ; upon entry di -> error flags
   639                                  ; destroys ax,bx,cx,dx
   640                                  
   641                                  print_lib_mod   PROC
   642 000002F0 803E[0000]00                cmp byte [is_inlib],0          ; see if processing in library
   643 000002F5 7460                        je  plm_ret             ; no
   644                                  
   645 000002F7 A0[0000]                    mov al,[tmod_name]        ; check that T-module name is nonzero
   646 000002FA 08C0                        or  al,al
   647 000002FC 7459                        je  plm_ret             ; don't print module name if zero length
   648                                  
   649                                  ; print module string and name
   650 000002FE BB[7F04]                    mov bx,OFFSET sttyp_module wrt DGROUP   ; write 'module' string
   651 00000301 8A4FFF                      mov cl,[bx-1]           ; get length of string
   652 00000304 89DA                        mov dx,bx               ; ds:dx -> string
   653 00000306 30ED                        xor ch,ch               ; zap high byte of cx
   654 00000308 BB0100                      mov bx,STDOUT           ; write to standard output device
   655 0000030B B440                        mov ah,40h              ; write to device
   656 0000030D CD21                        int 21h
   657                                  %IFNDEF JUNIOR
   658 0000030F E8(0000)                    call    restore_ems_map
   659                                  %ENDIF
   660                                  
   661 00000312 BB[0000]                    mov bx,OFFSET tmod_name wrt DGROUP
   662 00000315 89DA                        mov dx,bx
   663 00000317 31C9                        xor cx,cx               ; cx will contain number of chars in module name
   664                                  plm_loop:
   665 00000319 803F00                      cmp BYTE PTR [bx],0     ; see if zero terminator in file name found
   666 0000031C 7404                        je  plm_write           ; yes
   667 0000031E 41                          inc cx                  ; bump count of chars in string
   668 0000031F 43                          inc bx                  ; move to next char slot to test
   669 00000320 EBF7                        jmp SHORT plm_loop      ; loop back to test next char
   670                                  
   671                                  ; write library module name
   672                                  plm_write:
   673 00000322 BB0100                      mov bx,STDOUT           ; write to standard output device
   674 00000325 B440                        mov ah,40h              ; write to device
   675 00000327 CD21                        int 21h
   676                                  %IFNDEF JUNIOR
   677 00000329 E8(0000)                    call    restore_ems_map
   678                                  %ENDIF
   679                                  
   680 0000032C 8B05                        mov ax,[di]             ; get flags
   681 0000032E 2418                        and al,NO_OFF_ERRVAL    ; get offset/value bit field
   682 00000330 3C18                        cmp al,NO_OFF_ERRVAL    ; see if no file offset for error
   683 00000332 7423                        je plm_ret              ; no offset
   684                                  
   685                                  ; print module offset
   686                                  ; back off file offset from library module start prior to printing module offset
   687 00000334 A1[0000]                    mov ax,WORD PTR [file_pos_adj]
   688 00000337 8B1E[0200]                  mov bx,WORD PTR [file_pos_adj+2]
   689 0000033B 50                          push    ax              ; save old offset value
   690 0000033C 53                          push    bx
   691 0000033D 2B06[0000]                  sub ax,WORD PTR [lib_pos_adj] ; adjust for library module offset
   692 00000341 1B1E[0200]                  sbb bx,WORD PTR [lib_pos_adj+2]
   693 00000345 A3[0000]                    mov WORD PTR [file_pos_adj],ax    ; update new value to memory variable
   694 00000348 891E[0200]                  mov WORD PTR [file_pos_adj+2],bx
   695 0000034C E80900                      call    print_offset    ; print 'offset' string and file error offset in hex
   696 0000034F 8F06[0200]                  pop WORD [file_pos_adj+2] ; restore old value to memory variable
   697 00000353 8F06[0000]                  pop WORD [file_pos_adj]
   698                                  
   699                                  plm_ret:
   700 00000357 C3                          ret
   701                                  print_lib_mod   ENDP
   702                                  
   703                                  ;*****************************
   704                                  ;* PRINT_OFFSET              *
   705                                  ;*****************************
   706                                  
   707                                  ; print offset value in error feedback
   708                                  ; upon entry si holds file offset
   709                                  ; destroys ax,bx,cx,dx
   710                                  
   711                                  print_offset    PROC
   712 00000358 57                          push    di              ; save critical register
   713 00000359 56                          push    si
   714                                  
   715                                  ; print 'offset' string
   716 0000035A BB[1E04]                    mov bx,OFFSET sttyp_offset wrt DGROUP
   717 0000035D 8A4FFF                      mov cl,[bx-1]           ; get length of string
   718 00000360 89DA                        mov dx,bx               ; ds:dx -> string
   719 00000362 30ED                        xor ch,ch               ; zap high byte of cx
   720 00000364 BB0100                      mov bx,STDOUT           ; write to standard output device
   721 00000367 B440                        mov ah,40h              ; write to device
   722 00000369 CD21                        int 21h
   723                                  %IFNDEF JUNIOR
   724 0000036B E8(0000)                    call    restore_ems_map
   725                                  %ENDIF
   726                                  
   727 0000036E 30D2                        xor dl,dl               ; dl will hold count of chars in print string
   728 00000370 31FF                        xor di,di               ; init high word of offset
   729 00000372 0336[0000]                  add si,WORD PTR [file_pos_adj]    ; compute low word of offset
   730 00000376 133E[0200]                  adc di,WORD PTR [file_pos_adj+2]  ; compute high word of offset with carry
   731                                  
   732                                  ; di:si hold file offset
   733                                  po_2:
   734 0000037A BB[0400]                    mov bx,OFFSET number_hex wrt DGROUP ; point to number slot
   735 0000037D 30E4                        xor ah,ah               ; flag leading zero
   736 0000037F 89F9                        mov cx,di
   737 00000381 08ED                        or  ch,ch               ; see if high word high byte is zero
   738 00000383 7407                        je  po_3                ; yes
   739 00000385 88E9                        mov cl,ch               ; get value in cl
   740 00000387 E83301                      call    hex_to_ascii    ; convert high word, high byte to hex
   741 0000038A B401                        mov ah,1                ; flag no leading zero
   742                                  
   743                                  po_3:
   744 0000038C 89F9                        mov cx,di
   745 0000038E 08C9                        or  cl,cl               ; see if high word low byte is zero
   746 00000390 7504                        jne po_4                ; no
   747 00000392 08E4                        or  ah,ah               ; see if previous value printed
   748 00000394 7405                        je  po_5                ; no
   749                                  
   750                                  po_4:
   751 00000396 E82401                      call    hex_to_ascii    ; convert to hex
   752 00000399 B401                        mov ah,1                ; flag no leading zero
   753                                  
   754                                  po_5:
   755 0000039B 89F1                        mov cx,si
   756 0000039D 08ED                        or  ch,ch               ; see if low word, high byte is zero
   757 0000039F 7504                        jne po_6                ; no
   758 000003A1 08E4                        or  ah,ah               ; see if previous value printed
   759 000003A3 7407                        je  po_7                ; no
   760                                  
   761                                  po_6:
   762 000003A5 88E9                        mov cl,ch               ; get value in cl
   763 000003A7 E81301                      call    hex_to_ascii    ; convert to hex
   764 000003AA B401                        mov ah,1                ; flag no leading zero
   765                                  
   766                                  po_7:
   767 000003AC 89F1                        mov cx,si
   768 000003AE E80C01                      call    hex_to_ascii    ; convert to hex
   769 000003B1 C60768                      mov BYTE PTR [bx],'h'   ; terminate hex number with 'h' suffix
   770 000003B4 FEC2                        inc dl                  ; and bump count of chars
   771                                  
   772 000003B6 30ED                        xor ch,ch               ; zap high byte
   773 000003B8 88D1                        mov cl,dl               ; cx == number of chars to print
   774 000003BA BA[0400]                    mov dx,OFFSET number_hex wrt DGROUP ; ds:dx -> string to print
   775 000003BD BB0100                      mov bx,STDOUT           ; write to standard output device
   776 000003C0 B440                        mov ah,40h              ; write to device
   777 000003C2 CD21                        int 21h
   778                                  %IFNDEF JUNIOR
   779 000003C4 E8(0000)                    call    restore_ems_map
   780                                  %ENDIF
   781 000003C7 5E                          pop si
   782 000003C8 5F                          pop di                  ; restore critical register
   783 000003C9 C3                          ret
   784                                  print_offset    ENDP
   785                                  
   786                                  ;*****************************
   787                                  ;* PRINT_VALUE               *
   788                                  ;*****************************
   789                                  
   790                                  ; print value in error feedback
   791                                  ; upon entry di -> error type flags
   792                                  ; destroys ax,bx,cx
   793                                  
   794                                  print_value     PROC
   795 000003CA 8B0E[0200]                  mov cx,[error_value]      ; get value of error to print
   796 000003CE 30D2                        xor dl,dl               ; dl will hold count of chars in print string
   797 000003D0 BB[0400]                    mov bx,OFFSET number_hex wrt DGROUP ; point to number slot
   798 000003D3 30E4                        xor ah,ah               ; flag to put leading zero in front of number if necessary
   799 000003D5 F7051000                    test    WORD PTR [di],BIT16_ERRVAL  ; see if 8 or 16 bit value
   800 000003D9 7409                        je  pv_low_byte         ; 8 bit value, bypass 16 bit code
   801                                  
   802 000003DB 86E9                        xchg    ch,cl           ; get high byte in cl, save low byte in ch
   803 000003DD E8DD00                      call    hex_to_ascii    ; convert the high byte
   804 000003E0 86E9                        xchg    ch,cl           ; restore low byte to cl
   805 000003E2 B401                        mov ah,1                ; flag to hex_to_ascii procedure not to use leading zero
   806                                  
   807                                  pv_low_byte:
   808 000003E4 E8D600                      call    hex_to_ascii    ; convert low byte of value
   809 000003E7 C60768                      mov BYTE PTR [bx],'h'   ; terminate hex number with 'h' suffix
   810 000003EA FEC2                        inc dl                  ; and bump count of chars
   811                                  
   812 000003EC 30ED                        xor ch,ch
   813 000003EE 88D1                        mov cl,dl               ; cx == number of chars to print
   814 000003F0 BA[0400]                    mov dx,OFFSET number_hex wrt DGROUP ; ds:dx -> string to print
   815 000003F3 BB0100                      mov bx,STDOUT           ; write to standard output device
   816 000003F6 B440                        mov ah,40h              ; write to device
   817 000003F8 CD21                        int 21h
   818                                  %IFNDEF JUNIOR
   819 000003FA E8(0000)                    call    restore_ems_map
   820                                  %ENDIF
   821 000003FD A1[0200]                	mov ax, [error_value]
   822 00000400 F60510                  	testopt [di], BIT16_ERRVAL
   823 00000403 7502                    	jnz @F
   824 00000405 B400                    	mov ah, 0		; zero-extend
   825                                  @@:
   826 00000407 BB[0F00]                	mov bx, number_hex + 11	; -> last byte in buffer
   827 0000040A B90A00                  	mov cx, 10		; divisor
   828                                  .loop:
   829 0000040D 31D2                    	xor dx, dx
   830 0000040F F7F1                    	div cx			; ax = quotient, dl = remainder
   831 00000411 80C230                  	add dl, '0'		; make a digit
   832 00000414 8817                    	mov byte [bx], dl
   833 00000416 4B                      	dec bx
   834 00000417 85C0                    	test ax, ax		; quotient nonzero ?
   835 00000419 75F2                    	jnz .loop		; yes, loop -->
   836 0000041B 4B                      	dec bx
   837 0000041C C7073D20                	mov word [bx], "= "	; store text
   838 00000420 4B                      	dec bx			; -> start of text
   839 00000421 C60720                  	mov byte [bx], ' '
   840 00000424 B9[1000]                	mov cx, number_hex + 12	; -> behind buffer
   841 00000427 89DA                    	mov dx, bx
   842 00000429 29D9                    	sub cx, bx		; = length
   843 0000042B BB0100                  	mov bx, STDOUT
   844 0000042E B440                    	mov ah, 40h
   845 00000430 CD21                    	int 21h
   846                                  %IFNDEF JUNIOR
   847 00000432 E8(0000)                    call    restore_ems_map
   848                                  %ENDIF
   849 00000435 C3                          ret
   850                                  print_value     ENDP
   851                                  
   852                                  ;*****************************
   853                                  ;* PRINT_PROBLEM             *
   854                                  ;*****************************
   855                                  
   856                                  ; print linker problem
   857                                  ; upon entry di -> entry in error table
   858                                  ; destroys ax,bx,cx,dx
   859                                  
   860                                  print_problem   PROC
   861 00000436 BA[7103]                    mov dx,OFFSET string_problem wrt DGROUP ; point to Problem string
   862 00000439 8A0E[7003]                  mov cl,[string_pro_len]   ; get length of string
   863 0000043D BB0100                      mov bx,STDOUT           ; write to standard output device
   864 00000440 B440                        mov ah,40h              ; write to device
   865 00000442 CD21                        int 21h
   866                                  %IFNDEF JUNIOR
   867 00000444 E8(0000)                    call    restore_ems_map
   868                                  %ENDIF
   869                                  
   870 00000447 89FB                        mov bx,di               ; get previous offset in table
   871 00000449 8B7F02                      mov di,[bx+2]           ; get problem message address in di
   872 0000044C 89FA                        mov dx,di               ; DS:DX -> message to print
   873 0000044E 8A4DFF                      mov cl,[di-1]           ; cx = number of bytes to write
   874 00000451 89DF                        mov di,bx               ; save offset in table
   875 00000453 BB0100                      mov bx,STDOUT           ; write to standard output device
   876 00000456 B440                        mov ah,40h              ; write to device
   877 00000458 CD21                        int 21h
   878                                  %IFNDEF JUNIOR
   879 0000045A E8(0000)                    call    restore_ems_map
   880                                  %ENDIF
   881 0000045D C3                          ret
   882                                  print_problem   ENDP
   883                                  
   884                                  ;*****************************
   885                                  ;* PRINT_SOLUTION            *
   886                                  ;*****************************
   887                                  
   888                                  ; print solution to linker error/warning
   889                                  ; upon entry di -> entry in error table
   890                                  ; destroys ax,bx,cx,dx
   891                                  
   892                                  print_solution  PROC
   893 0000045E BA[8003]                    mov dx,OFFSET string_solution wrt DGROUP    ; point to Solution string
   894 00000461 8A0E[7F03]                  mov cl,[string_sol_len]   ; get length of string
   895 00000465 BB0100                      mov bx,STDOUT           ; write to standard output device
   896 00000468 B440                        mov ah,40h              ; write to device
   897 0000046A CD21                        int 21h
   898                                  %IFNDEF JUNIOR
   899 0000046C E8(0000)                    call    restore_ems_map
   900                                  %ENDIF
   901                                  
   902 0000046F 89FB                        mov bx,di               ; get previous offset in table
   903 00000471 8B7F04                      mov di,[bx+4]           ; get cause message address in di
   904 00000474 89FA                        mov dx,di               ; DS:DX -> message to print
   905 00000476 8A4DFF                      mov cl,[di-1]           ; cx = number of bytes to write
   906 00000479 89DF                        mov di,bx               ; save offset in table
   907 0000047B BB0100                      mov bx,STDOUT           ; write to standard output device
   908 0000047E B440                        mov ah,40h              ; write to device
   909 00000480 CD21                        int 21h
   910                                  %IFNDEF JUNIOR
   911 00000482 E8(0000)                    call    restore_ems_map
   912                                  %ENDIF
   913                                  
   914 00000485 89FB                        mov bx,di               ; get previous offset in table
   915 00000487 8B7F06                      mov di,[bx+6]           ; get solution message address in di
   916 0000048A 89FA                        mov dx,di               ; DS:DX -> message to print
   917 0000048C 89FE                        mov si,di
   918 0000048E 4E                          dec si                  ; SI -> number of bytes to write in line
   919 0000048F BB0100                      mov bx,STDOUT           ; write to standard output device
   920 00000492 8A4DFE                      mov cl,[di-2]           ; get line count in cx, ch always 0
   921                                  le_loop:
   922 00000495 51                          push    cx              ; save cx as is used for output
   923 00000496 89D7                        mov di,dx               ; save dx as it is used
   924 00000498 8A0E[8E03]                  mov cl,[string_sp_len]    ; get length of spacer
   925 0000049C BA[8F03]                    mov dx,OFFSET string_spacer wrt DGROUP  ; cr/lf+blanks string to print
   926 0000049F B440                        mov ah,40h              ; write to device
   927 000004A1 CD21                        int 21h
   928                                  %IFNDEF JUNIOR
   929 000004A3 E8(0000)                    call    restore_ems_map
   930                                  %ENDIF
   931 000004A6 89FA                        mov dx,di               ; restore previous dx value
   932 000004A8 8A0C                        mov cl,[si]             ; cx = number of bytes to write
   933 000004AA B440                        mov ah,40h              ; write to device
   934 000004AC CD21                        int 21h
   935                                  %IFNDEF JUNIOR
   936 000004AE E8(0000)                    call    restore_ems_map
   937                                  %ENDIF
   938 000004B1 01CE                        add si,cx               ; bump si to next message byte count
   939 000004B3 46                          inc si                  ; adjust for byte count byte
   940 000004B4 01CA                        add dx,cx               ; bump dx to next message line
   941 000004B6 42                          inc dx                  ; adjust for byte count byte
   942 000004B7 59                          pop cx                  ; restore line count
   943 000004B8 E2DB                        loop    le_loop         ; loop thru all lines in solution message
   944                                  
   945                                  ; print trailing CR/LF
   946 000004BA E92F03                      jmp NEAR PTR gwc_ret
   947                                  
   948                                  print_solution  ENDP
   949                                  
   950                                  ;*****************************
   951                                  ;* HEX_TO_ASCII              *
   952                                  ;*****************************
   953                                  
   954                                  ; convert 8 bit hex number to it's ASCII representation
   955                                  ; upon entry cl contains number
   956                                  ; ah == 0 if leading zero on numbers a-f, nonzero if not
   957                                  ; bx -> place to put digits
   958                                  ; destroys al,cl
   959                                  ; updates bx,dl (number of chars in string)
   960                                  
   961                                  hex_to_ascii    PROC
   962 000004BD 88C8                        mov al,cl
   963 000004BF 24F0                        and al,0f0h             ; get high nybble
   964 000004C1 D0E8                        shr al,1                ; make value relative zero
   965 000004C3 D0E8                        shr al,1
   966 000004C5 D0E8                        shr al,1
   967 000004C7 D0E8                        shr al,1                ; al has relative zero value
   968 000004C9 3C0A                        cmp al,0ah              ; see if need to use hex numbers a-f
   969 000004CB 720C                        jb  hta_3               ; no
   970                                  
   971 000004CD 08E4                        or  ah,ah               ; see if leading zero needed
   972 000004CF 7506                        jne hta_2               ; no
   973 000004D1 C60730                      mov BYTE PTR [bx],'0'   ; put leading zero in number
   974 000004D4 43                          inc bx                  ; point to next char slot
   975 000004D5 FEC2                        inc dl                  ; bump count of chars in number string
   976                                  hta_2:
   977 000004D7 0407                        add al,7                ; adjust for ASCII jump to alpha chars
   978                                  
   979                                  hta_3:
   980 000004D9 0430                        add al,30h              ; make number an ASCII representation
   981 000004DB 8807                        mov [bx],al             ; save it to number string
   982 000004DD 43                          inc bx                  ; point to next char slot
   983 000004DE FEC2                        inc dl                  ; bump count of chars in number string
   984                                  
   985 000004E0 80E10F                      and cl,0fh              ; get low nybble
   986 000004E3 80F90A                      cmp cl,0ah              ; see if hex number a-f
   987 000004E6 7203                        jb  hta_4               ; no
   988 000004E8 80C107                      add cl,7                ; adjust for ASCII jump to alpha chars
   989                                  hta_4:
   990 000004EB 80C130                      add cl,30h              ; make number an ASCII representation
   991 000004EE 880F                        mov [bx],cl             ; save it to number string
   992 000004F0 43                          inc bx                  ; point to next char slot
   993 000004F1 FEC2                        inc dl                  ; bump count of chars in number string
   994 000004F3 C3                          ret
   995                                  hex_to_ascii    ENDP
   996                                  
   997                                  ;*****************************
   998                                  ;* FIXUP_WARNING             *
   999                                  ;*****************************
  1000                                  
  1001                                  ; special format warning for fixup overflow
  1002                                  
  1003                                  fixup_warning   PROC
  1004 000004F4 06                          push    es              ; save all used registers
  1005 000004F5 56                          push    si
  1006 000004F6 57                          push    di
  1007 000004F7 52                          push    dx
  1008 000004F8 51                          push    cx
  1009 000004F9 53                          push    bx
  1010 000004FA 50                          push    ax              ; save error code, ax is used
  1011 000004FB 803E[0000]00                cmp byte [is_nowarn],0         ; see if warnings disabled
  1012 00000500 7403                        je  fw_1                ; no
  1013 00000502 E9FA01                      jmp NEAR PTR fw_ret     ; yes
  1014                                  
  1015                                  fw_1:
  1016                                  
  1017 00000505 BB[0000]                    mov bx,OFFSET error_table_start wrt DGROUP  ; point to start of error message address table
  1018 00000508 B82F00                      mov ax,FIXUP_OVRFLW_WARN    ; get fixup overflow warning value
  1019 0000050B D1E0                        shl ax,1                ; x2
  1020 0000050D D1E0                        shl ax,1                ; x4
  1021 0000050F D1E0                        shl ax,1                ; x8, ax holds offset into error table
  1022 00000511 01C3                        add bx,ax               ; bx -> proper entry in table
  1023 00000513 89DF                        mov di,bx               ; save -> entry
  1024                                  
  1025                                  ; print 'Warning in ' string
  1026 00000515 BB[5C04]                    mov bx,OFFSET sttyp_warning wrt DGROUP
  1027 00000518 8A4FFF                      mov cl,[bx-1]           ; get length of string
  1028 0000051B 89DA                        mov dx,bx               ; ds:dx -> string
  1029 0000051D 30ED                        xor ch,ch               ; zap high byte of cx
  1030 0000051F BB0100                      mov bx,STDOUT           ; write to standard output device
  1031 00000522 B440                        mov ah,40h              ; write to device
  1032 00000524 CD21                        int 21h
  1033                                  %IFNDEF JUNIOR
  1034 00000526 E8(0000)                    call    restore_ems_map
  1035                                  %ENDIF
  1036                                  
  1037 00000529 31C9                        xor cx,cx               ; cx will contain number of chars in file name
  1038 0000052B BA[0000]                    mov dx,OFFSET filename wrt DGROUP
  1039 0000052E 89D3                        mov bx,dx
  1040                                  fwloop1:
  1041 00000530 803F00                      cmp BYTE PTR [bx],0     ; see if zero terminator in file name found
  1042 00000533 7404                        je  fw_2                ; yes
  1043 00000535 41                          inc cx                  ; bump count of chars in string
  1044 00000536 43                          inc bx                  ; move to next char slot to test
  1045 00000537 EBF7                        jmp SHORT fwloop1       ; loop back to test next char
  1046                                  
  1047                                  ; write file name
  1048                                  fw_2:
  1049 00000539 BB0100                      mov bx,STDOUT           ; write to standard output device
  1050 0000053C B440                        mov ah,40h              ; write to device
  1051 0000053E CD21                        int 21h
  1052                                  %IFNDEF JUNIOR
  1053 00000540 E8(0000)                    call    restore_ems_map
  1054                                  %ENDIF
  1055                                  
  1056 00000543 E812FE                      call    print_offset
  1057                                  
  1058 00000546 31C0                        xor ax,ax               ; fake out print_lib_mod to print offset
  1059 00000548 A3[0200]                    mov [temp_flag],ax
  1060 0000054B 57                          push    di
  1061 0000054C BF[0200]                    mov di,OFFSET temp_flag wrt DGROUP
  1062 0000054F E89EFD                      call    print_lib_mod   ; check if processing library, print module name/offset if so
  1063 00000552 5F                          pop di
  1064                                  
  1065                                  ; print frame [group,segment,LOCATION] <name>
  1066 00000553 A1[0000]                    mov ax,[frame_ent_ptr]
  1067 00000556 09C0                        or  ax,ax               ; make sure non-null entry
  1068 00000558 7503                        jne fw_2a               ; okay
  1069 0000055A E9B700                      jmp NEAR PTR fw_print_target    ; null, move to print target
  1070                                  
  1071                                  ; print 'Frame ' string
  1072                                  fw_2a:
  1073 0000055D BA[6532]                    mov dx,OFFSET fw_frame_text wrt DGROUP
  1074 00000560 B90A00                      mov cx,10
  1075 00000563 BB0100                      mov bx,STDOUT
  1076 00000566 B440                        mov ah,40h              ; write to device
  1077 00000568 CD21                        int 21h
  1078                                  %IFNDEF JUNIOR
  1079 0000056A E8(0000)                    call    restore_ems_map
  1080                                  %ENDIF
  1081                                  
  1082                                  ; print 'group ', 'segment ', or 'LOCATION' string
  1083 0000056D A0[0000]                    mov al,[frame_method]
  1084                                  
  1085                                  fw_gsl:
  1086 00000570 08C0                        or  al,al
  1087 00000572 7435                        je  fw_fr_segment       ; segment frame
  1088 00000574 3C01                        cmp al,1
  1089 00000576 7429                        je  fw_fr_group         ; group frame
  1090 00000578 3C04                        cmp al,4
  1091 0000057A 7435                        je  fw_fr_loc           ; location frame
  1092 0000057C 3C02                        cmp al,2
  1093 0000057E 741A                        je  fw_fr_ext           ; external frame
  1094                                  
  1095                                  ; assume use of target index (frame method 5)
  1096 00000580 8B16[0000]                  mov dx,[targ_ent_ptr]     ; get target entry pointer
  1097 00000584 09D2                        or  dx,dx               ; make sure non-null
  1098 00000586 7503                        jne fw_2b               ; okay
  1099 00000588 E96201                      jmp NEAR PTR fw_print_prob  ; null, don't print any further
  1100                                  
  1101                                  fw_2b:
  1102 0000058B A0[0000]                    mov al,[target_method]
  1103 0000058E 2403                        and al,3                ; reduce to segment, group, or external value
  1104 00000590 3C02                        cmp al,2                ; check if external
  1105 00000592 74DC                        je  fw_gsl              ; yes, don't modify frame entry
  1106 00000594 8916[0000]                  mov [frame_ent_ptr],dx    ; make frame entry -> target entry
  1107 00000598 EBD6                        jmp SHORT fw_gsl        ; route based on target method
  1108                                  
  1109                                  fw_fr_ext:
  1110 0000059A A0[0000]                    mov al,[frext_ingroup]
  1111 0000059D 08C0                        or  al,al               ; see if external is in a group
  1112 0000059F 7408                        je  fw_fr_segment       ; no
  1113                                  
  1114                                  fw_fr_group:
  1115 000005A1 BA[8232]                    mov dx,OFFSET fw_group_text wrt DGROUP
  1116 000005A4 B90600                      mov cx,6
  1117 000005A7 EB0E                        jmp SHORT fw_print_gsl
  1118                                  
  1119                                  fw_fr_segment:
  1120 000005A9 BA[7A32]                    mov dx,OFFSET fw_seg_text wrt DGROUP
  1121 000005AC B90800                      mov cx,8
  1122 000005AF EB06                        jmp SHORT fw_print_gsl
  1123                                  
  1124                                  fw_fr_loc:
  1125 000005B1 BA[8832]                    mov dx,OFFSET fw_loc_text wrt DGROUP
  1126 000005B4 B90800                      mov cx,8
  1127                                  
  1128                                  fw_print_gsl:
  1129 000005B7 BB0100                      mov bx,STDOUT
  1130 000005BA B440                        mov ah,40h              ; write to device
  1131 000005BC CD21                        int 21h
  1132                                  %IFNDEF JUNIOR
  1133 000005BE E8(0000)                    call    restore_ems_map
  1134                                  %ENDIF
  1135                                  
  1136 000005C1 A0[0000]                    mov al,[frame_method]
  1137 000005C4 3C04                        cmp al,4                ; see if LOCATION frame method
  1138 000005C6 744C                        je  fw_print_target     ; yes, bypass printing name
  1139 000005C8 8B1E[0000]                  mov bx,[frame_ent_ptr]
  1140                                  
  1141                                  fw_3:
  1142 000005CC 08C0                        or  al,al               ; see if segment
  1143 000005CE 741E                        je  fw_frseg_name       ; yes
  1144 000005D0 3C01                        cmp al,1                ; see if group
  1145 000005D2 7412                        je  fw_frgrp_name       ; yes
  1146 000005D4 3C02                        cmp al,2                ; see if external
  1147 000005D6 7407                        je  fw_frext_name       ; yes
  1148                                  
  1149                                  ; assume use of target index (frame method 5)
  1150 000005D8 A0[0000]                    mov al,[target_method]
  1151 000005DB 2403                        and al,3                ; reduce to segment, group, or external value
  1152 000005DD EBED                        jmp SHORT fw_3          ; route based on target method
  1153                                  
  1154                                  fw_frext_name:
  1155 000005DF A0[0000]                    mov al,[frext_ingroup]
  1156 000005E2 08C0                        or  al,al               ; see if external is in a group
  1157 000005E4 7408                        je  fw_frseg_name       ; no
  1158                                  
  1159                                  fw_frgrp_name:
  1160 000005E6 8EDB                        mov ds,bx               ; ds -> frame entry
  1161 000005E8 C5160400                    lds dx,[4]           ; ds:dx -> group name
  1162 000005EC EB06                        jmp SHORT fw_fr_name
  1163                                  
  1164                                  fw_frseg_name:
  1165                                  ;***    cmp bx,-1               ; see if overlaid segment
  1166                                  ;***    jne fw_frseg2
  1167                                  ;***    mov dx,OFFSET ovlseg_text-8 wrt DGROUP  ; ds:dx -> 'Overlaid segment', minus adjustment
  1168                                  ;***    jmp SHORT fw_fr_name
  1169                                  
  1170                                  fw_frseg2:
  1171 000005EE 8EDB                        mov ds,bx               ; ds -> frame entry
  1172 000005F0 C5160800                    lds dx,[8]           ; ds:dx -> segment name
  1173                                  
  1174                                  fw_fr_name:
  1175 000005F4 83C208                      add dx,8                ; adjust past doubleword pointers
  1176 000005F7 89D3                        mov bx,dx               ; ds:bx -> string
  1177                                  
  1178                                  fwloop2:
  1179 000005F9 803F00                      cmp BYTE PTR [bx],0     ; see  if zero terminator
  1180 000005FC 7403                        je  fw_4                ; yes, end of name reached
  1181 000005FE 43                          inc bx
  1182 000005FF EBF8                        jmp SHORT fwloop2       ; not at end of name, keep counting chars
  1183                                  
  1184                                  ; ds:dx -> string, bx-dx holds string char count
  1185                                  fw_4:
  1186 00000601 29D3                        sub bx,dx
  1187 00000603 89D9                        mov cx,bx               ; cx holds count of chars to print
  1188 00000605 BB0100                      mov bx,STDOUT
  1189 00000608 B440                        mov ah,40h              ; write to device
  1190 0000060A CD21                        int 21h
  1191                                  %IFNDEF JUNIOR
  1192 0000060C E8(0000)                    call    restore_ems_map
  1193                                  %ENDIF
  1194                                  
  1195 0000060F B8[ssss]                    mov ax,DGROUP
  1196 00000612 8ED8                        mov ds,ax               ; restore ds -> warplink data
  1197                                  
  1198                                  ; print target [group,segment,symbol] <name>
  1199                                  fw_print_target:
  1200 00000614 A1[0000]                    mov ax,[targ_ent_ptr]
  1201 00000617 09C0                        or  ax,ax               ; make sure non-null entry
  1202 00000619 7503                        jne fw_4a               ; okay
  1203 0000061B E9CF00                      jmp NEAR PTR fw_print_prob  ; null, move to print problem code
  1204                                  
  1205                                  ; print 'Target ' string
  1206                                  fw_4a:
  1207 0000061E BA[6F32]                    mov dx,OFFSET fw_targ_text wrt DGROUP
  1208 00000621 B90B00                      mov cx,11
  1209 00000624 BB0100                      mov bx,STDOUT
  1210 00000627 B440                        mov ah,40h              ; write to device
  1211 00000629 CD21                        int 21h
  1212                                  %IFNDEF JUNIOR
  1213 0000062B E8(0000)                    call    restore_ems_map
  1214                                  %ENDIF
  1215                                  
  1216                                  ; print 'group ','segment ', or 'symbol ' string
  1217 0000062E A0[0000]                    mov al,[target_method]
  1218 00000631 2403                        and al,3                ; reduce to segment, group, or external value
  1219 00000633 7414                        je  fw_tar_segment      ; segment target
  1220 00000635 3C01                        cmp al,1
  1221 00000637 7408                        je  fw_tar_group        ; group target
  1222                                  
  1223                                  ; assume external target (target method 3)
  1224 00000639 BA[9032]                    mov dx,OFFSET fw_sym_text wrt DGROUP
  1225 0000063C B90700                      mov cx,7
  1226 0000063F EB0E                        jmp SHORT fw_print_gss
  1227                                  
  1228                                  fw_tar_group:
  1229 00000641 BA[8232]                    mov dx,OFFSET fw_group_text wrt DGROUP
  1230 00000644 B90700                      mov cx,7
  1231 00000647 EB06                        jmp SHORT fw_print_gss
  1232                                  
  1233                                  fw_tar_segment:
  1234 00000649 BA[7A32]                    mov dx,OFFSET fw_seg_text wrt DGROUP
  1235 0000064C B90800                      mov cx,8
  1236                                  
  1237                                  fw_print_gss:
  1238 0000064F BB0100                      mov bx,STDOUT
  1239 00000652 B440                        mov ah,40h              ; write to device
  1240 00000654 CD21                        int 21h
  1241                                  %IFNDEF JUNIOR
  1242 00000656 E8(0000)                    call    restore_ems_map
  1243                                  %ENDIF
  1244                                  
  1245                                  ; print target string
  1246 00000659 8B1E[0000]                  mov bx,[targ_ent_ptr]
  1247 0000065D A0[0000]                    mov al,[target_method]
  1248 00000660 2403                        and al,3
  1249 00000662 7417                        je  fw_tarseg_name      ; target segment
  1250 00000664 3C01                        cmp al,1                ; see if group
  1251 00000666 7408                        je  fw_targrp_name      ; yes
  1252                                  
  1253                                  ; assume use of external (target method 2/6)
  1254 00000668 8EDB                        mov ds,bx
  1255 0000066A C5160400                    lds dx,[4]           ; ds:dx -> pubdef name
  1256 0000066E EB14                        jmp SHORT fw_tar_name
  1257                                  
  1258                                  fw_targrp_name:
  1259 00000670 8EDB                        mov ds,bx               ; ds -> frame entry
  1260 00000672 C5160400                    lds dx,[4]           ; ds:dx -> group name
  1261 00000676 83C208                      add dx,8                ; adjust past double word pointers
  1262 00000679 EB09                        jmp SHORT fw_tar_name
  1263                                  
  1264                                  fw_tarseg_name:
  1265                                  ;***    cmp bx,-1               ; see if overlaid segment
  1266                                  ;***    jne fw_tarseg2
  1267                                  ;***    mov dx,OFFSET ovlseg_text wrt DGROUP    ; ds:dx -> 'Overlaid segment'
  1268                                  ;***    jmp SHORT fw_tar_name
  1269                                  
  1270                                  fw_tarseg2:
  1271 0000067B 8EDB                        mov ds,bx               ; ds -> frame entry
  1272 0000067D C5160800                    lds dx,[8]           ; ds:dx -> segment name
  1273 00000681 83C208                      add dx,8                ; adjust past double word pointers
  1274                                  
  1275                                  fw_tar_name:
  1276 00000684 89D3                        mov bx,dx               ; ds:bx -> string
  1277                                  
  1278                                  fwloop3:
  1279 00000686 803F00                      cmp BYTE PTR [bx],0     ; see  if zero terminator
  1280 00000689 7403                        je  fw_5                ; yes, end of name reached
  1281 0000068B 43                          inc bx
  1282 0000068C EBF8                        jmp SHORT fwloop3       ; not at end of name, keep counting chars
  1283                                  
  1284                                  ; ds:dx -> string, bx-dx holds string char count
  1285                                  fw_5:
  1286 0000068E 29D3                        sub bx,dx
  1287 00000690 89D9                        mov cx,bx               ; cx holds count of chars to print
  1288 00000692 BB0100                      mov bx,STDOUT
  1289 00000695 B440                        mov ah,40h              ; write to device
  1290 00000697 CD21                        int 21h
  1291                                  %IFNDEF JUNIOR
  1292 00000699 E8(0000)                    call    restore_ems_map
  1293                                  %ENDIF
  1294                                  
  1295 0000069C B8[ssss]                    mov ax,DGROUP
  1296 0000069F 8ED8                        mov ds,ax               ; restore ds -> warplink data
  1297                                  
  1298 000006A1 A0[0000]                    mov al,[target_method]
  1299 000006A4 3C02                        cmp al,2                ; see if a target displacement
  1300 000006A6 7745                        ja  fw_print_prob       ; no, don't print one
  1301                                  
  1302                                  ; print ', displacement ' string and displacement
  1303 000006A8 BA[9732]                    mov dx,OFFSET fw_disp_text wrt DGROUP
  1304 000006AB B90F00                      mov cx,15
  1305 000006AE BB0100                      mov bx,STDOUT
  1306 000006B1 B440                        mov ah,40h              ; write to device
  1307 000006B3 CD21                        int 21h
  1308                                  %IFNDEF JUNIOR
  1309 000006B5 E8(0000)                    call    restore_ems_map
  1310                                  %ENDIF
  1311                                  
  1312 000006B8 30D2                        xor dl,dl               ; dl will hold count of chars in print string
  1313 000006BA BB[0400]                    mov bx,OFFSET number_hex wrt DGROUP ; point to number slot
  1314 000006BD 30E4                        xor ah,ah               ; flag leading zero
  1315 000006BF 8A0E[0100]                  mov cl,BYTE PTR [target_disp+1]
  1316 000006C3 08C9                        or  cl,cl               ; see if high byte is zero
  1317 000006C5 7405                        je  fw_6                ; yes
  1318 000006C7 E8F3FD                      call    hex_to_ascii    ; convert high word, high byte to hex
  1319 000006CA B401                        mov ah,1                ; flag no leading zero
  1320                                  
  1321                                  fw_6:
  1322 000006CC 8A0E[0000]                  mov cl,BYTE PTR [target_disp]
  1323 000006D0 08C9                        or  cl,cl               ; see if low byte is zero
  1324 000006D2 7500                        jne fw_7                ; no
  1325                                  
  1326                                  fw_7:
  1327 000006D4 E8E6FD                      call    hex_to_ascii    ; convert to hex
  1328 000006D7 C60768                      mov BYTE PTR [bx],'h'   ; terminate hex number with 'h' suffix
  1329 000006DA FEC2                        inc dl                  ; and bump count of chars
  1330                                  
  1331 000006DC 30ED                        xor ch,ch               ; zap high byte
  1332 000006DE 88D1                        mov cl,dl               ; cx == number of chars to print
  1333 000006E0 BA[0400]                    mov dx,OFFSET number_hex wrt DGROUP ; ds:dx -> string to print
  1334 000006E3 BB0100                      mov bx,STDOUT           ; write to standard output device
  1335 000006E6 B440                        mov ah,40h              ; write to device
  1336 000006E8 CD21                        int 21h
  1337                                  %IFNDEF JUNIOR
  1338 000006EA E8(0000)                    call    restore_ems_map
  1339                                  %ENDIF
  1340                                  
  1341                                  fw_print_prob:
  1342 000006ED E846FD                      call    print_problem   ; print problem
  1343                                  
  1344 000006F0 A0[0200]                    mov al,[cascade_fixup]
  1345 000006F3 08C0                        or  al,al               ; see if solution was printed previously
  1346 000006F5 7508                        jne fw_ret              ; yes
  1347 000006F7 FEC0                        inc al                  ; no, store nonzero value to flag to indicate solution printed this pass
  1348 000006F9 A2[0200]                    mov [cascade_fixup],al    ; flag that problem/solution was printed
  1349                                  
  1350                                  fw_print_sol:
  1351 000006FC E85FFD                      call    print_solution  ; print solution
  1352                                  
  1353                                  fw_ret:
  1354 000006FF FF06[0000]                  inc word [warn_count]          ; bump count of warning messages
  1355 00000703 58                          pop ax                  ; restore registers
  1356 00000704 5B                          pop bx
  1357 00000705 59                          pop cx
  1358 00000706 5A                          pop dx
  1359 00000707 5F                          pop di
  1360 00000708 5E                          pop si
  1361 00000709 07                          pop es
  1362 0000070A C3                          ret
  1363                                  fixup_warning   ENDP
  1364                                  
  1365                                  ;*****************************
  1366                                  ;* DOS_ERROR                 *
  1367                                  ;*****************************
  1368                                  
  1369                                  ; ax has dos error upon entry
  1370                                  ; convert ax to warplink error code
  1371                                  
  1372                                  dos_error   PROC
  1373 0000070B BB[ssss]                    mov bx,DGROUP
  1374 0000070E 8EDB                        mov ds,bx               ; point data segment at WarpLink's data
  1375 00000710 C606[0000]00                mov BYTE [tmod_name],0    ; zero tmod_name so that if in library a bogus module name won't print
  1376 00000715 83F802                      cmp ax,2                ; file not found
  1377 00000718 7506                        jne de_2
  1378 0000071A B82400                      mov ax,DOS_FILE_FND_ERR
  1379                                  link_error_j1:
  1380 0000071D E9E0F8                      jmp link_error		; all DOS errors are fatal, don't return
  1381                                  
  1382                                  de_2:
  1383 00000720 83F803                      cmp ax,3                ; path not found
  1384 00000723 7505                        jne de_3
  1385 00000725 B82500                      mov ax,DOS_PATH_FND_ERR
  1386 00000728 EBF3                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1387                                  
  1388                                  de_3:
  1389 0000072A 83F804                      cmp ax,4                ; no open handles
  1390 0000072D 7505                        jne de_4
  1391 0000072F B82600                      mov ax,DOS_OUT_HAND_ERR
  1392 00000732 EBE9                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1393                                  
  1394                                  de_4:
  1395 00000734 83F805                      cmp ax,5                ; access denied
  1396 00000737 7505                        jne de_5
  1397 00000739 B82700                      mov ax,DOS_ACC_DEN_ERR
  1398 0000073C EBDF                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1399                                  
  1400                                  de_5:
  1401 0000073E 83F806                      cmp ax,6                ; invalid handle
  1402 00000741 7505                        jne de_6
  1403 00000743 B82800                      mov ax,DOS_INV_HAND_ERR
  1404 00000746 EBD5                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1405                                  
  1406                                  de_6:
  1407 00000748 83F807                      cmp ax,7                ; memory control blocks destroyed
  1408 0000074B 7505                        jne de_7
  1409 0000074D B82900                      mov ax,DOS_MCB_DSTRY_ERR
  1410 00000750 EBCB                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1411                                  
  1412                                  de_7:
  1413 00000752 83F808                      cmp ax,8                ; insufficient memory
  1414 00000755 7505                        jne de_8
  1415 00000757 B82A00                      mov ax,DOS_INSUF_MEM_ERR
  1416 0000075A EBC1                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1417                                  
  1418                                  de_8:
  1419 0000075C 83F809                      cmp ax,9                ; invalid memory block address
  1420 0000075F 7505                        jne de_9
  1421 00000761 B82B00                      mov ax,DOS_INV_MEM_BLK_ERR
  1422 00000764 EBB7                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1423                                  
  1424                                  de_9:
  1425 00000766 83F827                  	cmp ax, 27h
  1426 00000769 7505                    	jne .not27
  1427 0000076B B83A00                  	mov ax, DISK_FULL_ERR
  1428 0000076E EBAD                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1429                                  
  1430                                  .not27:
  1431 00000770 83F8FE                  	cmp ax, -2
  1432 00000773 7505                    	jne .notminus2
  1433 00000775 B86C00                  	mov ax, SHORT_READ_ERR
  1434 00000778 EBA3                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1435                                  
  1436                                  .notminus2:
  1437 0000077A B80400                      mov ax,UNKNOWN_ERR      ; not an expected dos error, change to unknown error
  1438 0000077D EB9E                        jmp link_error_j1 ; all DOS errors are fatal, don't return
  1439                                  dos_error   ENDP
  1440                                  
  1441                                  %IFNDEF JUNIOR
  1442                                  
  1443                                  ;*****************************
  1444                                  ;* CHECK_XMS_ERROR           *
  1445                                  ;*****************************
  1446                                  
  1447                                  ; check if XMS error, ax is ZERO if error upon entry
  1448                                  ; if error, bl has xms error upon entry
  1449                                  ; convert ax to warplink error code
  1450                                  
  1451                                  check_xms_error PROC
  1452 0000077F 09C0                        or  ax,ax
  1453 00000781 7401                        je  cxe_err             ; error occurred
  1454                                  
  1455                                  cxe_ret:
  1456 00000783 C3                          ret
  1457                                  
  1458                                  ; XMS error occurred
  1459                                  cxe_err:
  1460 00000784 80FBA0                      cmp bl,0a0h             ; see if no more free memory (not really an error)
  1461 00000787 74FA                        je  cxe_ret             ; no more free memory
  1462 00000789 88D9                        mov cl,bl               ; get 8 bit error code in cl
  1463 0000078B B84700                      mov ax,XMS_XMM_ERR
  1464 0000078E E96FF8                      jmp NEAR PTR link_error ; all XMS errors are fatal, don't return
  1465                                  
  1466                                  check_xms_error ENDP
  1467                                  
  1468                                  %ENDIF
  1469                                  
  1470                                  ;*****************************
  1471                                  ;* GIVE_WARN_COUNT           *
  1472                                  ;*****************************
  1473                                  
  1474                                  ; give count of warning messages, if any
  1475                                  ; destroys ax,bx,cx,dx,si,di
  1476                                  
  1477                                  give_warn_count PROC
  1478 00000791 833E[0000]00                cmp word [warn_count],0        ; see if any warning messages
  1479 00000796 7454                        je  gwc_ret             ; no
  1480 00000798 803E[0000]00                cmp byte [is_nowarn],0         ; see if warnings disabled
  1481 0000079D 754D                        jne gwc_ret             ; yes
  1482                                  
  1483                                  gwc_2:
  1484 0000079F BB[4732]                    mov bx,OFFSET warn_text wrt DGROUP
  1485 000007A2 8A4FFF                      mov cl,[bx-1]           ; get length of string
  1486 000007A5 89DA                        mov dx,bx               ; ds:dx -> string
  1487 000007A7 30ED                        xor ch,ch               ; zap high byte of cx
  1488 000007A9 BB0100                      mov bx,STDOUT           ; write to standard output device
  1489 000007AC B440                        mov ah,40h              ; write to device
  1490 000007AE CD21                        int 21h
  1491                                  %IFNDEF JUNIOR
  1492 000007B0 E8(0000)                    call    restore_ems_map
  1493                                  %ENDIF
  1494                                  
  1495 000007B3 BF[1000]                    mov di,OFFSET number_buff wrt DGROUP    ; point to temporary number buffer
  1496 000007B6 8CD8                        mov ax,ds
  1497 000007B8 8EC0                        mov es,ax               ; es -> warplink data
  1498 000007BA 31C9                        xor cx,cx               ; init count of digits
  1499 000007BC A1[0000]                    mov ax,[warn_count]       ; get count of warning messages
  1500                                  
  1501                                  gwc_divloop:
  1502 000007BF 31D2                        xor  dx,dx              ; zero high word value
  1503 000007C1 BB0A00                      mov  bx,0AH             ; divide by 10
  1504 000007C4 F7F3                        div  bx
  1505 000007C6 92                          xchg    dx,ax           ; swap quotient into dx, remainder into ax
  1506 000007C7 0C30                        or   al,30H             ; make remainder into ASCII number
  1507 000007C9 AA                          stosb                   ; save char to buffer
  1508 000007CA 41                          inc cx                  ; bump count of digits
  1509 000007CB 92                          xchg    dx,ax           ; restore quotient to ax
  1510 000007CC 09C0                        or   ax,ax              ; check if quotient is zero
  1511 000007CE 75EF                        jne  gwc_divloop        ; no, continue dividing
  1512                                  
  1513 000007D0 89FE                        mov si,di
  1514 000007D2 BF[0400]                    mov di,OFFSET number_hex wrt DGROUP ; place to put unreversed number
  1515 000007D5 89CB                        mov bx,cx               ; save count of chars in string
  1516                                  
  1517                                  gwc_revloop:
  1518 000007D7 4E                          dec si                  ; si -> char in reversed number buffer
  1519 000007D8 8A04                        mov al,[si]             ; get reversed char
  1520 000007DA AA                          stosb                   ; put in unreversed buffer
  1521 000007DB E2FA                        loop    gwc_revloop     ; unreverse as many chars as in number
  1522                                  
  1523 000007DD 89D9                        mov cx,bx               ; get count of chars in string
  1524 000007DF BA[0400]                    mov dx,OFFSET number_hex wrt DGROUP ;  ds:dx -> buffer to write
  1525 000007E2 BB0100                      mov bx,STDOUT           ; write to standard output device
  1526 000007E5 B440                        mov ah,40h              ; write to device
  1527 000007E7 CD21                        int 21h
  1528                                  %IFNDEF JUNIOR
  1529 000007E9 E8(0000)                    call    restore_ems_map
  1530                                  %ENDIF
  1531                                  
  1532                                  ; always give a trailing CR/LF, even if no warnings
  1533                                  gwc_ret:
  1534 000007EC B90200                      mov cx,2
  1535 000007EF BA[4732]                    mov dx,OFFSET warn_text wrt DGROUP
  1536 000007F2 BB0100                      mov bx,STDOUT
  1537 000007F5 B440                        mov ah,40h              ; write to device
  1538 000007F7 CD21                        int 21h
  1539                                  %IFNDEF JUNIOR
  1540 000007F9 E8(0000)                    call    restore_ems_map
  1541                                  %ENDIF
  1542 000007FC C3                          ret
  1543                                  give_warn_count ENDP
  1544                                  
  1545                                  END
