     1                                  ;*********************************************************************
     2                                  ;*   MLCLIP.ASM                                                      *
     3                                  ;*                                                                   *
     4                                  ;*   By:            Michael Devore                                   *
     5                                  ;*   Date:          02/12/93                                         *
     6                                  ;*   Model:         Small                                            *
     7                                  ;*   Version:       2.5                                              *
     8                                  ;*   Assembler:     MASM 5.0                                         *
     9                                  ;*   Environment:   MS-DOS 2.x+                                      *
    10                                  ;*                                                                   *
    11                                  ;*   Parse linker Clipper options, Clipper specific routines         *
    12                                  ;*                                                                   *
    13                                  ;*********************************************************************
    14                                  
    15                                  ;TITLE   WARPLINK mlclip
    16                                  ;PAGE    50,80
    17                                  
    18                                  ;.MODEL  SMALL
    19                                  
    20                                  ;*****************************
    21                                  ;* Include files             *
    22                                  ;*****************************
    23                                  
    24                                  [list -]
    29                                  
    30                                  ;*****************************
    31                                  ;* Public declarations       *
    32                                  ;*****************************
    33                                  
    34                                  ; procedures
    35                                  PUBLIC  parse_clp_option,do_incremental,decrypt
    36                                  PUBLIC  setup_incinfo,update_incinfo,check_cliplib,res_ilfseg
    37                                  PUBLIC  ilf_rewind,ilf_write_eof,delete_ilf_file
    38                                  PUBLIC	get_xxx_name
    39                                  PUBLIC	create_clipmod_entry,parse_clipper_symbols
    40                                  PUBLIC	pass2_clipcheck,fixup_clipper_tokens,process_symbol_table
    41                                  PUBLIC	compsym_fixup,clip_sym_fixup,clip_final_compress
    42                                  
    43                                  ; variables
    44                                  PUBLIC  smartmem_count,compress_this,new_ledata_offset
    45                                  PUBLIC	clip_fix_compress,must_parse_flag
    46                                  
    47                                  ;*****************************
    48                                  ;* Data begins               *
    49                                  ;*****************************
    50                                  
    51                                  .DATA
    52                                  
    53                                  ;*****************************
    54                                  ;* External declarations     *
    55                                  ;*****************************
    56                                  
    57                                  EXTRN   libtext:BYTE,objtext:BYTE,filename:BYTE
    58                                  EXTRN   name_field:BYTE,obj_block_ptr:WORD,lib_block_ptr:WORD
    59                                  EXTRN   libobj_flag:BYTE,mod_ovl_count:WORD,clp5_lib:BYTE
    60                                  EXTRN	clipper_segdef_ptr:WORD,first_clipmod_ptr:WORD,current_clipmod_ptr:WORD
    61                                  EXTRN	lxdata:BYTE,known_clipper:BYTE,symbol_overflow:BYTE
    62                                  EXTRN	clipper_segindex:WORD,unique_symbol_count:WORD,prev_symbol_count:WORD
    63                                  EXTRN	module_symbol_count:WORD
    64                                  EXTRN	current_clipmod_ptr:WORD,first_clipmod_ptr:WORD,compression_flag:BYTE
    65                                  EXTRN	is_summer87:BYTE,is_clipper5:BYTE
    66                                  EXTRN	data_offset:DWORD,rec_offset:WORD,data_rec_offset:WORD
    67                                  EXTRN	no_match_okay:BYTE
    68                                  
    69                                  ; initialized local variables
    70                                  
    71                                  ; bytes values
    72 00000000 00                      full_linkflag   DB  0       ; nonzero if automatic full link after incremental fails
    73 00000001 00                      EVEN
    74 00000002 01                      symseg_flag DB  1           ; nonzero if current LEDATA in SYMBOLS segment
    75                                                              ; during address resolution, 0 if SYMBOLS segment being resolved,
    76                                                              ; 1 if code, init to code (1) to catch later switchover to SYMBOLS
    77 00000003 00                      left_to_parse	DB	0		; length of symbol token left to parse
    78 00000004 00                      parse_length	DB	0		; nonzero if parsing asciiz token length (length of string)
    79 00000005 00                      old_parse_proc	DB	0		; nonzero if procedure already being compression processed
    80 00000006 00                      clip_fix_compress	DB	0	; nonzero if fixups following LEDATA contribute to compressed symbols
    81 00000007 00                      must_parse_flag	DB	0		; nonzero if must do symbol compression code at module end
    82                                  
    83                                  ; word values
    84                                  EVEN
    85 00000008 0000                    ilf_handle  DW  0           ; handle of open ilf file
    86 0000000A 0000                    change_flag     DW  0       ; nonzero if change occurred due to incremental link
    87 0000000C FFFF                    prev_obj_number DW  -1      ; number of previous object module in ilf entry list
    88 0000000E 0100                    ilf_ovl_count   DW  1       ; running count of overlays, start counting relative 1
    89 00000010 FFFF                    ilf_lastobj     DW  -1      ; last object module
    90 00000012 FFFF                    ilf_lastlib     DW  -1      ; last library
    91 00000014 FFFF                    lastused_lib    DW  -1      ; count of library name last received from get_curr_lib procedure
    92 00000016 FFFF                    smartmem_count  DW  -1      ; current library count of SmartMem library
    93 00000018 0000                    first_syment_ptr	DW	0	; pointer to first stored symbol table entry
    94                                  
    95                                  ; byte strings
    96 0000001A 31303032                tbuff   DB  '1002'          ; init'ed to ilf signature
    97 0000001E 0000000000000000                DW  0,0,0,0         ; space for pad value, bit flags, object file count, library count
    98                                  
    99                                  ; structures
   100                                  ILF_ENTRY_STRUC STRUC
   101 00000000 ????                        ie_bitflags DW  ?       ; bit flags of ilf entry
   102 00000002 ????                        ie_date     DW  ?       ; date of file
   103 00000004 ????                        ie_time     DW  ?       ; timestamp of file
   104 00000006 ????                        ie_objnum   DW  ?       ; object module/library number
   105 00000008 <res Dh>                    ie_objname  DB  13 DUP (?)  ; object file/library name
   106 00000015 ??                          ie_filler   DB  ?
   107 00000016 ????                        ie_segind   DW  ?       ; segdef index of segment
   108 00000018 ????                        ie_segsize  DW  ?       ; size of segment
   109 0000001A ????                        ie_fptrlow  DW  ?       ; pointer to location in exe/ovl file
   110 0000001C ????                        ie_ovlnum   DW  ?       ; overlay number if in overlay/high word of file pointer
   111 0000001E ????                        ie_offset   DW  ?       ; unused
   112                                  ILF_ENTRY_STRUC ENDS
   113                                  
   114                                  ilf_entry:
   115                                  istruc ILF_ENTRY_STRUC
   116                                  at ie_bitflags
   117                                  ilf_entry.ie_bitflags:
   118 00000026 00<rep 2h>              at ie_date
   119                                  ilf_entry.ie_date:
   120 00000028 00<rep 2h>              at ie_time
   121                                  ilf_entry.ie_time:
   122 0000002A 00<rep 2h>              at ie_objnum
   123                                  ilf_entry.ie_objnum:
   124 0000002C 00<rep 2h>              at ie_objname
   125                                  ilf_entry.ie_objname:
   126 0000002E 00<rep Dh>              at ie_filler
   127                                  ilf_entry.ie_filler:
   128 0000003B 00                      at ie_segind
   129                                  ilf_entry.ie_segind:
   130 0000003C 00<rep 2h>              at ie_segsize
   131                                  ilf_entry.ie_segsize:
   132 0000003E 00<rep 2h>              at ie_fptrlow
   133                                  ilf_entry.ie_fptrlow:
   134 00000040 00<rep 2h>              at ie_ovlnum
   135                                  ilf_entry.ie_ovlnum:
   136 00000042 00<rep 2h>              at ie_offset
   137                                  ilf_entry.ie_offset:
   138 00000044 00<rep 2h>              iend
   139                                  
   140                                  .DATA?
   141                                  
   142                                  ; uninitialized local variables
   143                                  
   144                                  ; byte values
   145                                  EVEN
   146 00000000 ??                      ilf_internal    DB  ?       ; nonzero if internal overlays are flagged
   147 00000001 ??                      EVEN
   148 00000002 ??                      ilf_inovl   DB  ?           ; nonzero if ilf segment is in an overlay
   149 00000003 ??                      clp_libflag DB  ?           ; nonzero if module is Clipper object module
   150 00000004 ??                      compress_this	DB	?		; nonzero if compressing this particular module
   151                                  
   152                                  ; word values
   153 00000005 ??                      EVEN
   154 00000006 ????                    ilf_fileseg DW  ?           ; segment of memory holding ilf file image
   155 00000008 ????                    obj_fileseg DW  ?           ; segment of memory holding obj file image
   156 0000000A ????                    symbols_buff    DW  ?       ; segment of memory holding symbols
   157 0000000C ????                    ilf_filesize    DW  ?       ; size of ilf file
   158 0000000E ????                    ilf_padval  DW  ?           ; pad value specified by ilf file
   159 00000010 ????                    entry_start DW  ?           ; first ilf entry of object module
   160 00000012 ????                    entry_end   DW  ?           ; entry after last ilf entry of object module
   161 00000014 ????                    ilf_lnames  DW  ?           ; current lnames index (relative zero)
   162 00000016 ????                    sym_lnames  DW  ?           ; Clipper SYMBOLS segment lnames index (relative zero)
   163 00000018 ????                    sym_segdef  DW  ?           ; Clipper SYMBOLS segment index number, relative zero
   164 0000001A ????                    ilf_segdef  DW  ?           ; current segdef index (relative zero)
   165 0000001C ????                    ilf_segpart_seg DW  ?       ; current ilf segment partition entry segment (for object module)
   166 0000001E ????                    ilf_segpart_ent DW  ?       ; current ilf segment partition entry number (for object module)
   167 00000020 ????                    start_lib_count DW  ?       ; library count at start sans defaults (amount specified in response file)
   168 00000022 ????                    parse_symoff	DW	?		; offset of parsed symbol from Clipper code fixup routine
   169 00000024 ????                    new_ledata_offset	DW	?	; data offset of LEDATA after compression, running total
   170 00000026 ????                    reloc_lowwater	DW	?		; low water mark for shift relocation entry locations on symbol compression
   171 00000028 ????                    prev_modsym_count	DW	?	; clipper symbols in module count prior to latest parse pass
   172                                  
   173                                  ovl_tbuff   EQU $           ; temporary buffer to read overlay file position from ovl header
   174                                  ovl_file_header  EQU $      ; first 5 words (10 bytes) of overlay file header go here
   175 0000002A ????                        ofh_ovl_number  DW  ?   ; number of overlay
   176 0000002C ????                        ofh_ovl_offset  DW  ?   ; Offset to overlay code
   177 0000002E ????                        ofh_ovl_size    DW  ?   ; Overlay code size in paragraphs
   178 00000030 ????                        ofh_near_vector DW  ?   ; Offset to near vector routine in segment
   179 00000032 ????                        ofh_reloc_count DW  ?   ; Relocation entry count
   180                                  
   181                                  ; doublewords
   182 00000034 ????????                prev_fileoff    DD  ?       ; previous file offset for read in object files
   183                                  
   184                                  ; byte strings
   185                                  symbol_buffer	LABEL	BYTE
   185                              <1> symbol_buffer :
   186 00000038 <res Ah>                exehdr_buff DB  10 DUP (?)  ; buffer to hold EXE header bytes
   187 00000042 <res Dh>                ilf_name    DB  13 DUP (?)
   188                                  
   189                                  ;*****************************
   190                                  ;* Constant data             *
   191                                  ;*****************************
   192                                  
   193                                  .CONST
   194                                  
   195 00000000 22                      fail_len        DB          fail_stop-fail_text
   196 00000001 0D0A436C6970706572-     fail_text       DB          CR,LF,'Clipper incremental link failed.'
   196 0000000A 20696E6372656D656E-
   196 00000013 74616C206C696E6B20-
   196 0000001C 6661696C65642E     
   197                                  fail_stop   equ   $
   198                                  
   199 00000023 20                      proceed_len     DB          proceed_stop-proceed_text
   200 00000024 0D0A50726F63656564-     proceed_text    DB          CR,LF,'Proceed with full link (Y/N)? '
   200 0000002D 20776974682066756C-
   200 00000036 6C206C696E6B202859-
   200 0000003F 2F4E293F20         
   201                                  proceed_stop    equ   $
   202                                  
   203 00000044 1C                      full_len        DB          full_stop-full_text
   204 00000045 0D0A50726F63656564-     full_text       DB          CR,LF,'Proceeding with full link.'
   204 0000004E 696E67207769746820-
   204 00000057 66756C6C206C696E6B-
   204 00000060 2E                 
   205                                  full_stop   equ   $
   206                                  
   207 00000061 1D                      nochange_len    DB          nochange_stop-nochange_text
   208 00000062 0D0A4E6F206368616E-     nochange_text   DB          CR,LF,'No changes made in program.'
   208 0000006B 676573206D61646520-
   208 00000074 696E2070726F677261-
   208 0000007D 6D2E               
   209                                  nochange_stop   equ   $
   210                                  
   211 0000007F 494C46                  ilf_text	DB	"ILF"
   212                                  
   213 00000082 969A9C9ED896969696-     summer87_token_list	DB	96h,9ah,9ch,9eh,0d8h,96h,96h,96h,96h,96h,96h,96h,96h,96h,96h,96h,96h
   213 0000008B 9696969696969696   
   214 00000093 060708090A0B0C0D0E-     clipper5_token_list	DB	6h,7h,8h,9h,0ah,0bh,0ch,0dh,0eh,0fh,10h,11h,12h,13h,14h,15h,16h
   214 0000009C 0F10111213141516   
   215                                  
   216                                  ; merge Clipper symbol tables into CONST data
   217                                  %include "mlsymtok.mac"
     1                              <1> ;*********************************************************************
     2                              <1> ;*   MLSYMTOK.INC                                                    *
     3                              <1> ;*                                                                   *
     4                              <1> ;*   By:            Michael Devore                                   *
     5                              <1> ;*   Date:          07/11/92                                         *
     6                              <1> ;*   Model:         Small                                            *
     7                              <1> ;*   Version:       2.5                                              *
     8                              <1> ;*   Assembler:     MASM 5.0                                         *
     9                              <1> ;*   Environment:   MS-DOS 2.x+                                      *
    10                              <1> ;*                                                                   *
    11                              <1> ;*   Clipper symbol token length lookup table                        *
    12                              <1> ;*                                                                   *
    13                              <1> ;*********************************************************************
    14                              <1> 
    15                              <1> summer87_table	EQU	$
    16 000000A4 00                  <1> 	DB	0	; illegal, 0
    17 000000A5 01                  <1> 	DB	1 	; ABS, 1
    18 000000A6 01                  <1> 	DB	1	; ACCEPT, 2
    19 000000A7 01                  <1> 	DB	1	; ACCUM, 3
    20 000000A8 01                  <1> 	DB	1	; ADD_FIELD, 4
    21 000000A9 01                  <1> 	DB	1	; AND, 5
    22 000000AA 01                  <1> 	DB	1	; APPEND, 6
    23 000000AB 01                  <1> 	DB	1	; ARRAY, 7
    24 000000AC 01                  <1> 	DB	1	; ARROW, 8
    25 000000AD 01                  <1> 	DB	1	; ASC, 9
    26 000000AE 01                  <1> 	DB	1	; AT, a
    27 000000AF 03                  <1> 	DB	3	; BEGIN_SEQ, b
    28 000000B0 01                  <1> 	DB	1	; BOF, c
    29 000000B1 01                  <1> 	DB	1	; BOX, d
    30 000000B2 01                  <1> 	DB	1	; BREAK, e
    31 000000B3 01                  <1> 	DB	1	; CALL, f
    32 000000B4 01                  <1> 	DB	1	; CDOW, 10
    33 000000B5 03                  <1> 	DB	3	; CHK_PC, 11
    34 000000B6 01                  <1> 	DB	1	; CHR, 12
    35 000000B7 01                  <1> 	DB	1	; CLR_RELATE, 13
    36 000000B8 01                  <1> 	DB	1	; CMONTH, 14
    37 000000B9 01                  <1> 	DB	1	; COL, 15
    38 000000BA 01                  <1> 	DB	1	; CTOD, 16
    39 000000BB 01                  <1> 	DB	1	; C_ALL, 17
    40 000000BC 01                  <1> 	DB	1	; C_DBF, 18
    41 000000BD 01                  <1> 	DB	1	; C_EOL, 19
    42 000000BE 01                  <1> 	DB	1	; C_EOS, 1a
    43 000000BF 01                  <1> 	DB	1	; C_GETS, 1b
    44 000000C0 01                  <1> 	DB	1	; C_SCREEN, 1c
    45 000000C1 01                  <1> 	DB	1	; DATE, 1d
    46 000000C2 01                  <1> 	DB	1	; DAY, 1e
    47 000000C3 01                  <1> 	DB	1	; DBF_CLOSE, 1f
    48 000000C4 01                  <1> 	DB	1	; DBF_COPY, 20
    49 000000C5 01                  <1> 	DB	1	; DBF_CREATE, 21
    50 000000C6 03                  <1> 	DB	3	; DBF_OPEN, 22
    51 000000C7 03                  <1> 	DB	3	; DBF_SELECT, 23
    52 000000C8 03                  <1> 	DB	3	; DBF_SET, 24
    53 000000C9 01                  <1> 	DB	1	; DBF_STRUX, 25
    54 000000CA 03                  <1> 	DB	3	; DBXBAG, 26
    55 000000CB 03                  <1> 	DB	3	; DECLARE, 27
    56 000000CC 01                  <1> 	DB	1	; DELETE, 28
    57 000000CD 01                  <1> 	DB	1	; DEL_FLAG, 29
    58 000000CE 01                  <1> 	DB	1	; DEL_MARK, 2a
    59 000000CF 01                  <1> 	DB	1	; DIVIDE, 2b
    60 000000D0 01                  <1> 	DB	1	; DO, 2c
    61 000000D1 03                  <1> 	DB	3	; DOS_CALL, 2d
    62 000000D2 01                  <1> 	DB	1	; DOW, 2e
    63 000000D3 01                  <1> 	DB	1	; DTOC, 2f
    64 000000D4 01                  <1> 	DB	1	; DTOS, 30
    65 000000D5 01                  <1> 	DB	1	; EEQ, 31 A
    66 000000D6 01                  <1> 	DB	1	; EJECT, 32
    67 000000D7 01                  <1> 	DB	1	; EMPTY, 33
    68 000000D8 01                  <1> 	DB	1	; ENDPROC, 34
    69 000000D9 01                  <1> 	DB	1	; END_SEQ, 35
    70 000000DA 03                  <1> 	DB	3	; QENVIRON, 36
    71 000000DB 01                  <1> 	DB	1	; EOF, 37
    72 000000DC 01                  <1> 	DB	1	; EQ, 38 S
    73 000000DD 01                  <1> 	DB	1	; EVENTS, 39
    74 000000DE 01                  <1> 	DB	1	; QEXP, 3a
    75 000000DF 01                  <1> 	DB	1	; EXPON, 3b
    76 000000E0 01                  <1> 	DB	1	; FALIAS0, 3c
    77 000000E1 01                  <1> 	DB	1	; FALIAS1, 3d
    78 000000E2 01                  <1> 	DB	1	; FALSE, 3e
    79 000000E3 01                  <1> 	DB	1	; FCOUNT, 3f
    80 000000E4 01                  <1> 	DB	1	; FIELDNAME, 40
    81 000000E5 01                  <1> 	DB	1	; ISFILE, 41
    82 000000E6 01                  <1> 	DB	1	; FLOCK, 42
    83 000000E7 01                  <1> 	DB	1	; FOUND, 43
    84 000000E8 01                  <1> 	DB	1	; FSELECT0, 44
    85 000000E9 01                  <1> 	DB	1	; FSELECT1, 45
    86 000000EA 01                  <1> 	DB	1	; FUNC, 46
    87 000000EB 01                  <1> 	DB	1	; GE, 47
    88 000000EC 01                  <1> 	DB	1	; GET, 48
    89 000000ED 01                  <1> 	DB	1	; GET_RANGE, 49
    90 000000EE 01                  <1> 	DB	1	; GET_SP, 4a
    91 000000EF 01                  <1> 	DB	1	; GET_VALID, 4b
    92 000000F0 01                  <1> 	DB	1	; GOTO, 4c
    93 000000F1 01                  <1> 	DB	1	; GOTO_BOTT, 4d
    94 000000F2 01                  <1> 	DB	1	; GOTO_TOP, 4e
    95 000000F3 01                  <1> 	DB	1	; GT, 4f
    96 000000F4 00                  <1> 	DB	0	; UNKNOWN, 50
    97 000000F5 01                  <1> 	DB	1	; INKEY0, 51
    98 000000F6 01                  <1> 	DB	1	; INKEY1, 52
    99 000000F7 01                  <1> 	DB	1	; INPUT, 53
   100 000000F8 01                  <1> 	DB	1	; INSTR, 54
   101 000000F9 01                  <1> 	DB	1	; INT, 55
   102 000000FA 01                  <1> 	DB	1	; ISCOLOR, 56
   103 000000FB 03                  <1> 	DB	3	; JEOF, 57
   104 000000FC 03                  <1> 	DB	3	; JFALSE, 58
   105 000000FD 03                  <1> 	DB	3	; JUMP, 59
   106 000000FE 03                  <1> 	DB	3	; JTRUE, 5a
   107 000000FF 01                  <1> 	DB	1	; KEYBOARD, 5b
   108 00000100 00                  <1> 	DB	0	; UNKNOWN, 5c
   109 00000101 01                  <1> 	DB	1	; LASTKEY, 5d
   110 00000102 01                  <1> 	DB	1	; LASTREC, 5e
   111 00000103 01                  <1> 	DB	1	; LBL, 5f
   112 00000104 03                  <1> 	DB	3	; LBL_BEGIN, 60
   113 00000105 01                  <1> 	DB	1	; LBL_END, 61
   114 00000106 01                  <1> 	DB	1	; LE, 62
   115 00000107 01                  <1> 	DB	1	; LEN, 63
   116 00000108 03                  <1> 	DB	3	; LINE, 64
   117 00000109 01                  <1> 	DB	1	; LOCATEP, 65
   118 0000010A 01                  <1> 	DB	1	; LOCK, 66
   119 0000010B 01                  <1> 	DB	1	; LOGQ, 67
   120 0000010C 01                  <1> 	DB	1	; LOWER, 68
   121 0000010D 01                  <1> 	DB	1	; LT, 69
   122 0000010E 01                  <1> 	DB	1	; LTRIM, 6a
   123 0000010F 01                  <1> 	DB	1	; MAX, 6b
   124 00000110 01                  <1> 	DB	1	; MEMORY, 6c
   125 00000111 01                  <1> 	DB	1	; MENU, 6d
   126 00000112 01                  <1> 	DB	1	; MIN, 6e
   127 00000113 01                  <1> 	DB	1	; MINUS, 6f
   128 00000114 01                  <1> 	DB	1	; MODULUS, 70
   129 00000115 01                  <1> 	DB	1	; MONTH, 71
   130 00000116 01                  <1> 	DB	1	; MULT, 72
   131 00000117 01                  <1> 	DB	1	; M_RESTORE, 73
   132 00000118 01                  <1> 	DB	1	; M_SAVE, 74
   133 00000119 01                  <1> 	DB	1	; NE, 75
   134 0000011A 01                  <1> 	DB	1	; NEGATE, 76
   135 0000011B 01                  <1> 	DB	1	; NETNAME, 77
   136 0000011C 03                  <1> 	DB	3	; NEXT, 78
   137 0000011D 01                  <1> 	DB	1	; NOT, 79
   138 0000011E 01                  <1> 	DB	1	; NTX_CLOSE, 7a
   139 0000011F 01                  <1> 	DB	1	; NTX_CREATE, 7b
   140 00000120 01                  <1> 	DB	1	; NTX_KEY, 7c
   141 00000121 01                  <1> 	DB	1	; NTX_OPEN, 7d
   142 00000122 01                  <1> 	DB	1	; NTX_ORDER, 7e
   143 00000123 01                  <1> 	DB	1	; CNULL, 7f
   144 00000124 01                  <1> 	DB	1	; ONE1, 80
   145 00000125 01                  <1> 	DB	1	; OR, 81
   146 00000126 01                  <1> 	DB	1	; PACK, 82
   147 00000127 01                  <1> 	DB	1	; PARAM, 83
   148 00000128 01                  <1> 	DB	1	; PCOL, 84
   149 00000129 01                  <1> 	DB	1	; PCOUNT, 85
   150 0000012A 01                  <1> 	DB	1	; PLUS, 86
   151 0000012B 01                  <1> 	DB	1	; POP, 87
   152 0000012C 01                  <1> 	DB	1	; POPF, 88
   153 0000012D 01                  <1> 	DB	1	; POPM, 89
   154 0000012E 01                  <1> 	DB	1	; POPM2, 8a
   155 0000012F 01                  <1> 	DB	1	; POS_XY, 8b
   156 00000130 01                  <1> 	DB	1	; PRINT, 8c
   157 00000131 01                  <1> 	DB	1	; PRINTNL, 8d
   158 00000132 01                  <1> 	DB	1	; PRINTS, 8e
   159 00000133 01                  <1> 	DB	1	; PRIVATE, 8f
   160 00000134 00                  <1> 	DB	0	; UNKNOWN, 90
   161 00000135 01                  <1> 	DB	1	; PROCLINE, 91
   162 00000136 01                  <1> 	DB	1	; PROCNAME, 92
   163 00000137 01                  <1> 	DB	1	; PROMPT, 93
   164 00000138 01                  <1> 	DB	1	; PROW, 94
   165 00000139 01                  <1> 	DB	1	; PUBLIC, 95
   166 0000013A 03                  <1> 	DB	3	; PUSHA, 96
   167 0000013B 19                  <1> 	DB	25	; PUSHSTR, 97
   168 0000013C 00                  <1> 	DB	0	; UNKNOWN, 98
   169 0000013D 03                  <1> 	DB	3	; PUSHINT, 99
   170 0000013E 03                  <1> 	DB	3	; PUSHM, 9a
   171 0000013F 0B                  <1> 	DB	11	; PUSHDBL, 9b
   172 00000140 03                  <1> 	DB	3	; PUSHP, 9c
   173 00000141 01                  <1> 	DB	1	; PUSHS, 9d
   174 00000142 03                  <1> 	DB	3	; PUSHV, 9e
   175 00000143 03                  <1> 	DB	3	; PUSHKEY, 9f
   176 00000144 01                  <1> 	DB	1	; PUTM0, a0
   177 00000145 01                  <1> 	DB	1	; QUIT, a1 S
   178 00000146 01                  <1> 	DB	1	; READ, a2
   179 00000147 01                  <1> 	DB	1	; READVAR, a3
   180 00000148 01                  <1> 	DB	1	; RECALL, a4
   181 00000149 01                  <1> 	DB	1	; RECNO, a5
   182 0000014A 03                  <1> 	DB	3	; REEF, a6
   183 0000014B 01                  <1> 	DB	1	; REINDEX, a7
   184 0000014C 01                  <1> 	DB	1	; RELEASE, a8
   185 0000014D 01                  <1> 	DB	1	; REP, a9
   186 0000014E 01                  <1> 	DB	1	; REPLICATE, aa
   187 0000014F 03                  <1> 	DB	3	; REP_BEGIN, ab
   188 00000150 01                  <1> 	DB	1	; REP_END, ac
   189 00000151 03                  <1> 	DB	3	; REWIND, ad
   190 00000152 01                  <1> 	DB	1	; ROUND, ae
   191 00000153 01                  <1> 	DB	1	; ROW, af
   192 00000154 01                  <1> 	DB	1	; SAVE_RET, b0
   193 00000155 01                  <1> 	DB	1	; SAY, b1
   194 00000156 03                  <1> 	DB	3	; SCOPE_DEC, b2
   195 00000157 03                  <1> 	DB	3	; SCOPE_SET, b3
   196 00000158 01                  <1> 	DB	1	; SCR_RESTORE, b4
   197 00000159 01                  <1> 	DB	1	; SCR_SAVE, b5
   198 0000015A 01                  <1> 	DB	1	; SECONDS, b6
   199 0000015B 01                  <1> 	DB	1	; SEEK, b7
   200 0000015C 01                  <1> 	DB	1	; SELECT, b8
   201 0000015D 01                  <1> 	DB	1	; SET_ALTER, b9
   202 0000015E 01                  <1> 	DB	1	; SET_COLOR, ba
   203 0000015F 03                  <1> 	DB	3	; SET_DATE, bb
   204 00000160 01                  <1> 	DB	1	; SET_DECIMALS, bc
   205 00000161 01                  <1> 	DB	1	; SET_DEFAULT, bd
   206 00000162 01                  <1> 	DB	1	; SET_DELIM, be
   207 00000163 03                  <1> 	DB	3	; SET_DEVICE, bf
   208 00000164 01                  <1> 	DB	1	; SET_FILTER, c0
   209 00000165 01                  <1> 	DB	1	; SET_FMT, c1
   210 00000166 01                  <1> 	DB	1	; SET_FUNCTION, c2
   211 00000167 01                  <1> 	DB	1	; SET_KEY, c3
   212 00000168 01                  <1> 	DB	1	; SET_LOCATE, c4
   213 00000169 01                  <1> 	DB	1	; SET_MARGIN, c5
   214 0000016A 03                  <1> 	DB	3	; SET_OFF, c6
   215 0000016B 03                  <1> 	DB	3	; SET_ON, c7
   216 0000016C 01                  <1> 	DB	1	; SET_PATH, c8
   217 0000016D 03                  <1> 	DB	3	; SET_PC, c9
   218 0000016E 01                  <1> 	DB	1	; SET_PRINTER, ca
   219 0000016F 01                  <1> 	DB	1	; SET_RELATE, cb
   220 00000170 01                  <1> 	DB	1	; SKIP, cc
   221 00000171 01                  <1> 	DB	1	; SORT, cd
   222 00000172 03                  <1> 	DB	3	; SORT_BEGIN, ce
   223 00000173 01                  <1> 	DB	1	; SORT_END, cf
   224 00000174 01                  <1> 	DB	1	; SPACE, d0
   225 00000175 01                  <1> 	DB	1	; SPUSHM, d1
   226 00000176 01                  <1> 	DB	1	; QSQRT, d2
   227 00000177 01                  <1> 	DB	1	; STR1, d3
   228 00000178 01                  <1> 	DB	1	; STR2, d4
   229 00000179 01                  <1> 	DB	1	; STR3, d5
   230 0000017A 01                  <1> 	DB	1	; SUB2, d6
   231 0000017B 01                  <1> 	DB	1	; SUB3, d7
   232 0000017C 03                  <1> 	DB	3	; SYMBOL, d8
   233 0000017D 01                  <1> 	DB	1	; TIME, d9
   234 0000017E 03                  <1> 	DB	3	; TO_DEST, da
   235 0000017F 01                  <1> 	DB	1	; TRANS, db
   236 00000180 01                  <1> 	DB	1	; TRIM, dc
   237 00000181 01                  <1> 	DB	1	; TRUE, dd
   238 00000182 01                  <1> 	DB	1	; TYPE, de
   239 00000183 03                  <1> 	DB	3	; UNLOCK, df
   240 00000184 01                  <1> 	DB	1	; UPDATED, e0
   241 00000185 01                  <1> 	DB	1	; UPPER, e1
   242 00000186 01                  <1> 	DB	1	; USED, e2
   243 00000187 01                  <1> 	DB	1	; VAL, e3
   244 00000188 01                  <1> 	DB	1	; WAIT, e4
   245 00000189 01                  <1> 	DB	1	; WAVE, e5
   246 0000018A 01                  <1> 	DB	1	; WAVEA, e6
   247 0000018B 01                  <1> 	DB	1	; WAVEL, e7
   248 0000018C 01                  <1> 	DB	1	; WAVEP, e8
   249 0000018D 01                  <1> 	DB	1	; WORD, e9
   250 0000018E 03                  <1> 	DB	3	; WSET, ea
   251 0000018F 01                  <1> 	DB	1	; WSYMBOL, eb
   252 00000190 01                  <1> 	DB	1	; XRELEASE, ec
   253 00000191 01                  <1> 	DB	1	; YEAR, ed
   254 00000192 01                  <1> 	DB	1	; ZAP, ee
   255 00000193 01                  <1> 	DB	1	; ZER0, ef
   256 00000194 00                  <1> 	DB	0	; ILLEGAL, f0
   257 00000195 00                  <1> 	DB	0	; ILLEGAL, f1
   258 00000196 00                  <1> 	DB	0	; ILLEGAL, f2
   259 00000197 00                  <1> 	DB	0	; ILLEGAL, f3
   260 00000198 00                  <1> 	DB	0	; ILLEGAL, f4
   261 00000199 00                  <1> 	DB	0	; ILLEGAL, f5
   262 0000019A 00                  <1> 	DB	0	; ILLEGAL, f6
   263 0000019B 00                  <1> 	DB	0	; ILLEGAL, f7
   264 0000019C 00                  <1> 	DB	0	; ILLEGAL, f8
   265 0000019D 00                  <1> 	DB	0	; ILLEGAL, f9
   266 0000019E 00                  <1> 	DB	0	; ILLEGAL, fa
   267 0000019F 00                  <1> 	DB	0	; ILLEGAL, fb
   268 000001A0 00                  <1> 	DB	0	; ILLEGAL, fc
   269 000001A1 00                  <1> 	DB	0	; ILLEGAL, fd
   270 000001A2 00                  <1> 	DB	0	; ILLEGAL, fe
   271 000001A3 00                  <1> 	DB	0	; ILLEGAL, ff
   272                              <1> 
   273                              <1> clipper5_table	EQU	$
   274 000001A4 01                  <1>  	DB	1	; 00, NOP
   275 000001A5 19                  <1>  	DB	25	; 01, PUSHC
   276 000001A6 01                  <1>  	DB	1	; 02, ERR1
   277 000001A7 01                  <1>  	DB	1	; 03, ERR2
   278 000001A8 01                  <1>  	DB	1	; 04, ERR3
   279 000001A9 0B                  <1>  	DB	11	; 05, PUSHN
   280 000001AA 03                  <1>  	DB	3	; 06, POPF
   281 000001AB 03                  <1>  	DB	3	; 07, POPM
   282 000001AC 03                  <1>  	DB	3	; 08, POPQF
   283 000001AD 03                  <1>  	DB	3	; 09, PUSHA
   284 000001AE 03                  <1>  	DB	3	; 0a, PUSHF
   285 000001AF 03                  <1>  	DB	3	; 0b, PUSHM
   286 000001B0 03                  <1>  	DB	3	; 0c, PUSHMR
   287 000001B1 03                  <1>  	DB	3	; 0d, PUSHP
   288 000001B2 03                  <1>  	DB	3	; 0e, PUSHQF
   289 000001B3 03                  <1>  	DB	3	; 0f, PUSHV
   290 000001B4 03                  <1>  	DB	3	; 10, SFRAME
   291 000001B5 03                  <1>  	DB	3	; 11, SINIT
   292 000001B6 03                  <1>  	DB	3	; 12, SYMBOL
   293 000001B7 03                  <1>  	DB	3	; 13, SYMF
   294 000001B8 01                  <1>  	DB	1	; 14, ERR4
   295 000001B9 01                  <1>  	DB	1	; 15, ERR5
   296 000001BA 01                  <1>  	DB	1	; 16, ERR6
   297 000001BB 01                  <1>  	DB	1	; 17, ERR7
   298 000001BC 01                  <1>  	DB	1	; 18, ERR8
   299 000001BD 03                  <1>  	DB	3	; 19, BEGIN_SEQ
   300 000001BE 03                  <1>  	DB	3	; 1a, JDBG
   301 000001BF 03                  <1>  	DB	3	; 1b, JF
   302 000001C0 03                  <1>  	DB	3	; 1c, JFPT
   303 000001C1 03                  <1>  	DB	3	; 1d, JISW
   304 000001C2 03                  <1>  	DB	3	; 1e, JMP
   305 000001C3 03                  <1>  	DB	3	; 1f, JNEI
   306 000001C4 03                  <1>  	DB	3	; 20, JT
   307 000001C5 03                  <1>  	DB	3	; 21, JTPF
   308 000001C6 01                  <1>  	DB	1	; 22, ERR9
   309 000001C7 03                  <1>  	DB	3	; 23, PUSHBL
   310 000001C8 03                  <1>  	DB	3	; 24, ARRAYATI
   311 000001C9 03                  <1>  	DB	3	; 25, ARRAYPUTI
   312 000001CA 03                  <1>  	DB	3	; 26, CALL
   313 000001CB 03                  <1>  	DB	3	; 27, DO
   314 000001CC 03                  <1>  	DB	3	; 28, FRAME
   315 000001CD 03                  <1>  	DB	3	; 29, FUNC
   316 000001CE 03                  <1>  	DB	3	; 2a, LINE
   317 000001CF 03                  <1>  	DB	3	; 2b, MAKEA
   318 000001D0 03                  <1>  	DB	3	; 2c, MAKELA
   319 000001D1 03                  <1>  	DB	3	; 2d, PARAMS
   320 000001D2 03                  <1>  	DB	3	; 2e, POPFL
   321 000001D3 03                  <1>  	DB	3	; 2f, POPL
   322 000001D4 03                  <1>  	DB	3	; 30, POPS
   323 000001D5 03                  <1>  	DB	3	; 31, PRIVATES
   324 000001D6 01                  <1>  	DB	1	; 32, ERR10
   325 000001D7 03                  <1>  	DB	3	; 33, PUBLICS
   326 000001D8 03                  <1>  	DB	3	; 34, PUSHFL
   327 000001D9 03                  <1>  	DB	3	; 35, PUSHFLR
   328 000001DA 03                  <1>  	DB	3	; 36, PUSHI
   329 000001DB 03                  <1>  	DB	3	; 37, PUSHL
   330 000001DC 03                  <1>  	DB	3	; 38, PUSHLR
   331 000001DD 03                  <1>  	DB	3	; 39, PUSHS
   332 000001DE 03                  <1>  	DB	3	; 3a, PUSHSR
   333 000001DF 03                  <1>  	DB	3	; 3b, PUSHW
   334 000001E0 03                  <1>  	DB	3	; 3c, SEND
   335 000001E1 03                  <1>  	DB	3	; 3d, XBLOCK
   336 000001E2 01                  <1>  	DB	1	; 3e, ERR11
   337 000001E3 01                  <1>  	DB	1	; 3f, ERR12
   338 000001E4 01                  <1>  	DB	1	; 40, ERR13
   339 000001E5 01                  <1>  	DB	1	; 41, ERR14
   340 000001E6 01                  <1>  	DB	1	; 42, ERR15
   341 000001E7 01                  <1>  	DB	1	; 43, ERR16
   342 000001E8 01                  <1>  	DB	1	; 44, ERR17
   343 000001E9 01                  <1>  	DB	1	; 45, ERR18
   344 000001EA 01                  <1>  	DB	1	; 46, ERR19
   345 000001EB 01                  <1>  	DB	1	; 47, ERR20
   346 000001EC 01                  <1>  	DB	1	; 48, ERR21
   347 000001ED 01                  <1>  	DB	1	; 49, ERR22
   348 000001EE 05                  <1>  	DB	5	; 4a, MPOPF
   349 000001EF 05                  <1>  	DB	5	; 4b, MPOPM
   350 000001F0 05                  <1>  	DB	5	; 4c, MPOPQF
   351 000001F1 05                  <1>  	DB	5	; 4d, MPUSHA
   352 000001F2 05                  <1>  	DB	5	; 4e, MPUSHF
   353 000001F3 05                  <1>  	DB	5	; 4f, MPUSHM
   354 000001F4 05                  <1>  	DB	5	; 50, MPUSHMR
   355 000001F5 05                  <1>  	DB	5	; 51, MPUSHP
   356 000001F6 05                  <1>  	DB	5	; 52, MPUSHQF
   357 000001F7 05                  <1>  	DB	5	; 53, MPUSHV
   358 000001F8 05                  <1>  	DB	5	; 54, MSYMBOL
   359 000001F9 05                  <1>  	DB	5	; 55, MSYMF
   360 000001FA 01                  <1>  	DB	1	; 56, ABS
   361 000001FB 01                  <1>  	DB	1	; 57, AND
   362 000001FC 01                  <1>  	DB	1	; 58, ARRAYAT
   363 000001FD 01                  <1>  	DB	1	; 59, ARRAYPUT
   364 000001FE 01                  <1>  	DB	1	; 5a, BREAK
   365 000001FF 01                  <1>  	DB	1	; 5b, DEC
   366 00000200 01                  <1>  	DB	1	; 5c, DIVIDE
   367 00000201 01                  <1>  	DB	1	; 5d, DOOP
   368 00000202 01                  <1>  	DB	1	; 5e, EEQ
   369 00000203 01                  <1>  	DB	1	; 5f, ENDBLOCK
   370 00000204 01                  <1>  	DB	1	; 60, ENDPROC
   371 00000205 01                  <1>  	DB	1	; 61, END_SEQ
   372 00000206 01                  <1>  	DB	1	; 62, EQ
   373 00000207 01                  <1>  	DB	1	; 63, EVENTS
   374 00000208 01                  <1>  	DB	1	; 64, FALSE
   375 00000209 01                  <1>  	DB	1	; 65, GE
   376 0000020A 01                  <1>  	DB	1	; 66, GT
   377 0000020B 01                  <1>  	DB	1	; 67, INC
   378 0000020C 01                  <1>  	DB	1	; 68, LE
   379 0000020D 01                  <1>  	DB	1	; 69, LT
   380 0000020E 01                  <1>  	DB	1	; 6a, MINUS
   381 0000020F 01                  <1>  	DB	1	; 6b, MULT
   382 00000210 01                  <1>  	DB	1	; 6c, NE
   383 00000211 01                  <1>  	DB	1	; 6d, ERR23
   384 00000212 01                  <1>  	DB	1	; 6e, NEGATE
   385 00000213 01                  <1>  	DB	1	; 6f, NOP2
   386 00000214 01                  <1>  	DB	1	; 70, NOT
   387 00000215 01                  <1>  	DB	1	; 71, NULL
   388 00000216 01                  <1>  	DB	1	; 72, ONE1
   389 00000217 01                  <1>  	DB	1	; 73, OR
   390 00000218 01                  <1>  	DB	1	; 74, PCOUNT
   391 00000219 01                  <1>  	DB	1	; 75, PLUS
   392 0000021A 01                  <1>  	DB	1	; 76, POP
   393 0000021B 01                  <1>  	DB	1	; 77, PUSHRV
   394 0000021C 01                  <1>  	DB	1	; 78, QSELF
   395 0000021D 01                  <1>  	DB	1	; 79, SAVE_RET
   396 0000021E 01                  <1>  	DB	1	; 7a, TRUE
   397 0000021F 01                  <1>  	DB	1	; 7b, UNDEF
   398 00000220 01                  <1>  	DB	1	; 7c, ZER0
   399 00000221 01                  <1>  	DB	1	; 7d, ZZBLOCK
   400 00000222 01                  <1>  	DB	1	; 7e, AXPRIN
   401 00000223 01                  <1>  	DB	1	; 7f, AXPROUT
   402 00000224 01                  <1>  	DB	1	; 80, BOF
   403 00000225 01                  <1>  	DB	1	; 81, DELETED
   404 00000226 01                  <1>  	DB	1	; 82, EOF
   405 00000227 01                  <1>  	DB	1	; 83, FCOUNT
   406 00000228 01                  <1>  	DB	1	; 84, FIELDNAME
   407 00000229 01                  <1>  	DB	1	; 85, FLOCK
   408 0000022A 01                  <1>  	DB	1	; 86, FOUND
   409 0000022B 01                  <1>  	DB	1	; 87, FSELECT0
   410 0000022C 01                  <1>  	DB	1	; 88, FSELECT1
   411 0000022D 01                  <1>  	DB	1	; 89, LASTREC
   412 0000022E 01                  <1>  	DB	1	; 8a, LOCK
   413 0000022F 01                  <1>  	DB	1	; 8b, RECNO
   414 00000230 01                  <1>  	DB	1	; 8c, BNAMES
   415 00000231 01                  <1>  	DB	1	; 8d, LNAMES
   416 00000232 01                  <1>  	DB	1	; 8e, SNAMES
   417 00000233 01                  <1>  	DB	1	; 8f, SRCNAME
   418 00000234 01                  <1>  	DB	1	; 90, TYPE
   419 00000235 01                  <1>  	DB	1	; 91, WAVE
   420 00000236 01                  <1>  	DB	1	; 92, WAVEA
   421 00000237 01                  <1>  	DB	1	; 93, WAVEF
   422 00000238 01                  <1>  	DB	1	; 94, WAVEL
   423 00000239 01                  <1>  	DB	1	; 95, WAVEP
   424 0000023A 01                  <1>  	DB	1	; 96, WAVEPOP
   425 0000023B 01                  <1>  	DB	1	; 97, WAVEPOPF
   426 0000023C 01                  <1>  	DB	1	; 98, WAVEPOPQ
   427 0000023D 01                  <1>  	DB	1	; 99, WAVEQ
   428 0000023E 01                  <1>  	DB	1	; 9a, WSYMBOL
   429 0000023F 01                  <1>  	DB	1	; 9b, AADD
   430 00000240 01                  <1>  	DB	1	; 9c, ASC
   431 00000241 01                  <1>  	DB	1	; 9d, AT
   432 00000242 01                  <1>  	DB	1	; 9e, CDOW
   433 00000243 01                  <1>  	DB	1	; 9f, CHR
   434 00000244 01                  <1>  	DB	1	; a0, CMONTH
   435 00000245 01                  <1>  	DB	1	; a1, CTOD
   436 00000246 01                  <1>  	DB	1	; a2, DATE
   437 00000247 01                  <1>  	DB	1	; a3, DAY
   438 00000248 01                  <1>  	DB	1	; a4, DOW
   439 00000249 01                  <1>  	DB	1	; a5, DTOC
   440 0000024A 01                  <1>  	DB	1	; a6, DTOS
   441 0000024B 01                  <1>  	DB	1	; a7, EMPTY
   442 0000024C 01                  <1>  	DB	1	; a8, QEXP
   443 0000024D 01                  <1>  	DB	1	; a9, EXPON
   444 0000024E 01                  <1>  	DB	1	; aa, INSTR
   445 0000024F 01                  <1>  	DB	1	; ab, INT
   446 00000250 01                  <1>  	DB	1	; ac, LEFT
   447 00000251 01                  <1>  	DB	1	; ad, LEN
   448 00000252 01                  <1>  	DB	1	; ae, LOGQ
   449 00000253 01                  <1>  	DB	1	; af, LOWER
   450 00000254 01                  <1>  	DB	1	; b0, LTRIM
   451 00000255 01                  <1>  	DB	1	; b1, MAX
   452 00000256 01                  <1>  	DB	1	; b2, MIN
   453 00000257 01                  <1>  	DB	1	; b3, MODULUS
   454 00000258 01                  <1>  	DB	1	; b4, MONTH
   455 00000259 01                  <1>  	DB	1	; b5, REPLICATE
   456 0000025A 01                  <1>  	DB	1	; b6, ROUND
   457 0000025B 01                  <1>  	DB	1	; b7, SECONDS
   458 0000025C 01                  <1>  	DB	1	; b8, SPACE
   459 0000025D 01                  <1>  	DB	1	; b9, QSQRT
   460 0000025E 01                  <1>  	DB	1	; ba, STR1
   461 0000025F 01                  <1>  	DB	1	; bb, STR2
   462 00000260 01                  <1>  	DB	1	; bc, STR3
   463 00000261 01                  <1>  	DB	1	; bd, SUB2
   464 00000262 01                  <1>  	DB	1	; be, SUB3
   465 00000263 01                  <1>  	DB	1	; bf, TIME
   466 00000264 01                  <1>  	DB	1	; c0, TRIM
   467 00000265 01                  <1>  	DB	1	; c1, UPPER
   468 00000266 01                  <1>  	DB	1	; c2, VAL
   469 00000267 01                  <1>  	DB	1	; c3, VALTYPE
   470 00000268 01                  <1>  	DB	1	; c4, WORD
   471 00000269 01                  <1>  	DB	1	; c5, YEAR
   472 0000026A 01                  <1>  	DB	1	; c6, TRANS
   473 0000026B 01                  <1>  	DB	1	; c7, COL
   474 0000026C 01                  <1>  	DB	1	; c8, DEVPOS
   475 0000026D 01                  <1>  	DB	1	; c9, INKEY0
   476 0000026E 01                  <1>  	DB	1	; ca, INKEY1
   477 0000026F 01                  <1>  	DB	1	; cb, PCOL
   478 00000270 01                  <1>  	DB	1	; cc, PROW
   479 00000271 01                  <1>  	DB	1	; cd, ROW
   480 00000272 01                  <1>  	DB	1	; ce, SETPOS
   481 00000273 01                  <1>  	DB	1	; cf, SETPOSBS
   482 00000274 00                  <1>  	DB	0	; d0,
   483 00000275 00                  <1>  	DB	0	; d1,
   484 00000276 00                  <1>  	DB	0	; d2,
   485 00000277 00                  <1>  	DB	0	; d3,
   486 00000278 00                  <1>  	DB	0	; d4,
   487 00000279 00                  <1>  	DB	0	; d5,
   488 0000027A 00                  <1>  	DB	0	; d6,
   489 0000027B 00                  <1>  	DB	0	; d7,
   490 0000027C 00                  <1>  	DB	0	; d8,
   491 0000027D 00                  <1>  	DB	0	; d9,
   492 0000027E 00                  <1>  	DB	0	; da,
   493 0000027F 00                  <1>  	DB	0	; db,
   494 00000280 00                  <1>  	DB	0	; dc,
   495 00000281 00                  <1>  	DB	0	; dd,
   496 00000282 00                  <1>  	DB	0	; de,
   497 00000283 00                  <1>  	DB	0	; df,
   498 00000284 00                  <1>  	DB	0	; e0,
   499 00000285 00                  <1>  	DB	0	; e1,
   500 00000286 00                  <1>  	DB	0	; e2,
   501 00000287 00                  <1>  	DB	0	; e3,
   502 00000288 00                  <1>  	DB	0	; e4,
   503 00000289 00                  <1>  	DB	0	; e5,
   504 0000028A 00                  <1>  	DB	0	; e6,
   505 0000028B 00                  <1>  	DB	0	; e7,
   506 0000028C 00                  <1>  	DB	0	; e8,
   507 0000028D 00                  <1>  	DB	0	; e9,
   508 0000028E 00                  <1>  	DB	0	; ea,
   509 0000028F 00                  <1>  	DB	0	; eb,
   510 00000290 00                  <1>  	DB	0	; ec,
   511 00000291 00                  <1>  	DB	0	; ed,
   512 00000292 00                  <1>  	DB	0	; ee,
   513 00000293 00                  <1>  	DB	0	; ef,
   514 00000294 00                  <1>  	DB	0	; f0,
   515 00000295 00                  <1>  	DB	0	; f1,
   516 00000296 00                  <1>  	DB	0	; f2,
   517 00000297 00                  <1>  	DB	0	; f3,
   518 00000298 00                  <1>  	DB	0	; f4,
   519 00000299 00                  <1>  	DB	0	; f5,
   520 0000029A 00                  <1>  	DB	0	; f6,
   521 0000029B 00                  <1>  	DB	0	; f7,
   522 0000029C 00                  <1>  	DB	0	; f8,
   523 0000029D 00                  <1>  	DB	0	; f9,
   524 0000029E 00                  <1>  	DB	0	; fa,
   525 0000029F 00                  <1>  	DB	0	; fb,
   526 000002A0 00                  <1>  	DB	0	; fc,
   527 000002A1 00                  <1>  	DB	0	; fd,
   528 000002A2 00                  <1>  	DB	0	; fe,
   529 000002A3 00                  <1>  	DB	0	; ff,
   218                                  
   219                                  ;*****************************
   220                                  ;* Code begins               *
   221                                  ;*****************************
   222                                  
   223                                  .CODE
   224                                  
   225                                  ;*****************************
   226                                  ;* External declarations     *
   227                                  ;*****************************
   228                                  
   229                                  EXTRN   link_error:NEAR,dos_error:NEAR,check_libobj_path:NEAR
   230                                  EXTRN   get_curr_obj:NEAR,get_curr_lib:NEAR,restore_ems_map:NEAR
   231                                  EXTRN	file_not_found:NEAR,is_terminator:NEAR
   232                                  EXTRN	alloc_memory:NEAR,load_file:NEAR
   233                                  EXTRN	find_pubdecl_entry:NEAR,get_hash:NEAR
   234                                  EXTRN	get_pubdecl_entry:NEAR,add_pubdef_name:NEAR
   235                                  
   236                                  ;*****************************
   237                                  ;* PARSE_CLP_OPTION          *
   238                                  ;*****************************
   239                                  
   240                                  ; parse Clipper option
   241                                  ; ds:si -> third char of option (at 'P')
   242                                  ; cx -> start of option
   243                                  ; destroys ax,dx,es
   244                                  ; updates si
   245                                  
   246                                  parse_clp_option    PROC
   247 00000000 AC                          lodsb                   ; eat 'P'
   248 00000001 AC                          lodsb                   ; get Clipper option
   249 00000002 3C35                        cmp al,'5'              ; see if Clipper 5 option
   250 00000004 7419                        je  par_clp5            ; yes
   251 00000006 3C41                        cmp al,'A'              ; check bounds
   252 00000008 7302                    	jae	par_lower			; okay
   253                                  
   254                                  ; option out of bounds
   255                                  to_par_bad:
   256 0000000A EB6D                    	jmp	NEAR PTR par_bad
   257                                  
   258                                  par_lower:
   259 0000000C 3C7A                        cmp al,'z'              ; check bounds
   260 0000000E 77FA                        ja  to_par_bad          ; too high
   261                                  
   262 00000010 24DF                        and al,0dfh             ; force char to uppercase
   263                                  
   264 00000012 3C49                        cmp al,'I'              ; see if incremental link
   265 00000014 7545                        jne par_smartmem        ; no
   266 00000016 A2[0000]                    mov [is_clpinc],al        ; set clipper incremental link flag
   267 00000019 C606[0000]00            	mov	byte [is_sympac],0			; reset symbol table compaction option
   268 0000001E C3                          ret
   269                                  
   270                                  par_clp5:
   271 0000001F A2[0000]                    mov [is_clip5],al         ; set Clipper 5.0 option
   272 00000022 A2[0000]                    mov [is_anyovls],al       ; overlays specified
   273 00000025 8A04                        mov al,[si]             ; peek ahead at next char
   274 00000027 3C3A                        cmp al,':'              ; see if colon (supplied library name)
   275 00000029 7401                        je  par_c5_lib          ; yes
   276 0000002B C3                          ret                     ; no, done parsing option
   277                                  
   278                                  par_c5_lib:
   279 0000002C 89DA                        mov dx,bx               ; save bx value
   280 0000002E BB[0000]                    mov bx,OFFSET clp5_lib wrt DGROUP
   281 00000031 AC                          lodsb                   ; gobble colon
   282                                  
   283                                  par_c5_loop:
   284 00000032 AC                          lodsb                   ; get lib name char
   285 00000033 E8(0000)                	call	is_terminator	; see if file name parse terminator
   286 00000036 7415                        je 	par_c5_done         ; yes, done
   287 00000038 3C61                        cmp al,'a'              ; check lower bounds
   288 0000003A 7206                        jb  par_c5_save         ; not a lowercase letter
   289 0000003C 3C7A                        cmp al,'z'              ; check upper bounds
   290 0000003E 7702                        ja  par_c5_save         ; not a lowercase letter
   291 00000040 2C20                        sub al,32               ; force lowercase to uppercase
   292                                  
   293                                  par_c5_save:
   294 00000042 8807                        mov [bx],al             ; save library name char
   295 00000044 43                          inc bx
   296 00000045 81FB[0D00]                  cmp bx,OFFSET clp5_lib+13 wrt DGROUP    ; make sure not past 12 chars in name
   297 00000049 732E                        jae par_bad             ; too many chars in name
   298 0000004B EBE5                        jmp SHORT par_c5_loop
   299                                  
   300                                  par_c5_done:
   301 0000004D 4E                          dec si                  ; drop si back to -> terminating char
   302 0000004E 81FB[0000]                  cmp bx,OFFSET clp5_lib wrt DGROUP   ; make sure non-null name
   303 00000052 7425                        je  par_bad             ; no library name supplied
   304 00000054 30C0                        xor al,al               ; null terminate string
   305 00000056 8807                        mov [bx],al             ; transfer it
   306 00000058 89D3                        mov bx,dx               ; restore bx value
   307 0000005A C3                          ret                     ; done
   308                                  
   309                                  par_smartmem:
   310                                  %IFNDEF DEMO
   311 0000005B 3C53                        cmp al,'S'              ; see if SMARTMEM.XXX SmartMem routines used
   312 0000005D 7504                        jne par_full            ; no
   313 0000005F A2[0000]                    mov [is_smartmem],al      ; set smartmem flag
   314 00000062 C3                          ret
   315                                  %ENDIF
   316                                  
   317                                  par_full:
   318 00000063 3C46                        cmp al,'F'              ; see if automatic full link after incremental failed
   319 00000065 7504                        jne eat_colon           ; no
   320 00000067 A2[0000]                    mov [full_linkflag],al    ; set full link flag
   321 0000006A C3                          ret
   322                                  
   323                                  eat_colon:
   324 0000006B 88C4                        mov ah,al               ; save option in ah
   325 0000006D AC                          lodsb                   ; get colon following overlay option char
   326 0000006E 3C3A                        cmp al,':'              ; must be colon
   327 00000070 7507                        jne par_bad             ; not a colon
   328                                  
   329                                  ; check for valid option char in ah
   330                                  par_check_valid:
   331 00000072 80FC50                      cmp ah,'P'              ; check if segment pad value
   332 00000075 7502                        jne par_bad             ; no, no more valid options
   333 00000077 EB06                        jmp SHORT par_get_pad   ; get segment pad value
   334                                  
   335                                  ; bad option or value
   336                                  par_bad:
   337 00000079 B80500                      mov ax,BAD_OPTION_ERR
   338 0000007C E9(0000)                    jmp NEAR PTR link_error ; transfer control to error handler
   339                                  
   340                                  ; segment pad value
   341                                  par_get_pad:
   342 0000007F 31D2                        xor dx,dx               ; dx == multiplier
   343                                  
   344                                  pgp_2:
   345 00000081 AC                          lodsb                   ; get number
   346 00000082 3C30                        cmp al,'0'              ; see nondigit
   347 00000084 721B                        jb  pgp_done            ; yes, done
   348 00000086 3C39                        cmp al,'9'              ; see nondigit
   349 00000088 7717                        ja  pgp_done            ; yes
   350                                  
   351 0000008A 240F                        and al,0fh              ; change from ASCII to actual value
   352 0000008C 08F6                        or  dh,dh               ; see if value too large for shift
   353 0000008E 75E9                        jne par_bad             ; yes
   354 00000090 88C6                        mov dh,al               ; save value
   355 00000092 88D0                        mov al,dl               ; get pre-existing value
   356 00000094 B40A                        mov ah,10
   357 00000096 F6E4                        mul ah                  ; multiply pre-existing value by 10 (shift placeholder)
   358 00000098 92                          xchg    dx,ax           ; save shifted value back to dx, get new value in ah
   359 00000099 88E0                        mov al,ah               ; get value in low byte
   360 0000009B 30E4                        xor ah,ah               ; zap high byte
   361 0000009D 01C2                        add dx,ax               ; add in new value
   362 0000009F EBE0                        jmp SHORT pgp_2         ; get next digit
   363                                  
   364                                  pgp_done:
   365 000000A1 08F6                        or  dh,dh               ; check if absolute maximum exceeded
   366 000000A3 75D4                        jne par_bad             ; yes
   367 000000A5 8816[0000]                  mov [inc_padval],dl       ; save segment pad value
   368 000000A9 4E                          dec si                  ; drop si back to -> nondigit char
   369 000000AA C3                          ret                     ; done
   370                                  parse_clp_option    ENDP
   371                                  
   372                                  ;*********************************************************************
   373                                  ;
   374                                  ; Structure of files with ILF (incremental link file) extension
   375                                  ;
   376                                  ; version -- 4 bytes of ASCII, current '1002'
   377                                  ; object module count -- 1 word
   378                                  ; library count -- 1 word
   379                                  ; pad value -- 1 word, default 16 (10h)
   380                                  ; bit flags -- 1 word, bit 0 set if internal overlays
   381                                  ; executable name without path or drive spec -- 13 bytes
   382                                  ;       currently always ILF name with EXE extension
   383                                  ; filler -- 7 bytes
   384                                  ; Total control information byte size == 32 bytes, 2 paragraphs
   385                                  ; One or more entries for each Clipper object module segment or library
   386                                  ; structured as follows:
   387                                  ;   bit flags -- 1 word, bit 0 set if changeable segment
   388                                  ;                        bit 1 set if Clipper SYMBOLS segment
   389                                  ;                        bit 2 set if library file (never changeable)
   390                                  ;                        bit 3 set if in overlay file
   391                                  ;                        bit 4 set if non-Clipper object module, nonchangeable
   392                                  ;                        bit 15 set if end of file (ignore following bytes)
   393                                  ;   date -- 1 word
   394                                  ;   time -- 1 word
   395                                  ;   object number -- 1 word
   396                                  ;   object/library name, no path/drive spec -- 13 bytes
   397                                  ;   filler (word aligner) -- 1 byte
   398                                  ;   segment index -- 1 word
   399                                  ;   segment size -- 1 word
   400                                  ;   EXE file pointer to segment location in EXE file -- 1 doubleword
   401                                  ;       OR overlay number
   402                                  ;   change offset, offset to start writing bytes past fixups -- 1 word
   403                                  ; Total entry size, each -- 32 bytes
   404                                  ;
   405                                  ;*********************************************************************
   406                                  
   407                                  ;*****************************
   408                                  ;* DO_INCREMENTAL            *
   409                                  ;*****************************
   410                                  
   411                                  ; if pre-existing ILF file, perform incremental link
   412                                  ; otherwise set up ILF file
   413                                  ; destroys ax,bx,cx,dx,si,di,es
   414                                  
   415                                  do_incremental  PROC
   416 000000AB BB[7F00]                	mov	bx,OFFSET ilf_text wrt DGROUP	; bx -> proper extension
   417 000000AE BF[4200]                    mov di,OFFSET ilf_name wrt DGROUP   ; di -> place to put ILF name
   418 000000B1 89FA                    	mov	dx,di				; ds:dx -> filespec
   419 000000B3 E8F007                      call    get_xxx_name    ; get ILF name
   420 000000B6 B8003D                      mov ax,3d00h            ; open file for reading
   421 000000B9 CD21                        int 21h
   422 000000BB E8(0000)                    call    restore_ems_map
   423 000000BE 7371                        jnc di_ilf_found        ; file found okay
   424 000000C0 E8(0000)                	call	file_not_found	; check for file not found errors
   425                                  
   426                                  ; no (or invalid) ILF file was found, create one
   427                                  di_new_ilf:
   428 000000C3 A1[0000]                    mov ax,[lib_count]
   429 000000C6 A3[2000]                    mov [start_lib_count],ax  ; save starting library count (don't track default libs)
   430 000000C9 BA[4200]                    mov dx,OFFSET ilf_name wrt DGROUP   ; ds:dx -> filespec
   431 000000CC 31C9                        xor cx,cx               ; normal file
   432 000000CE B43C                        mov ah,3ch              ; create or truncate file
   433 000000D0 CD21                        int 21h
   434 000000D2 E8(0000)                    call    restore_ems_map
   435 000000D5 7303                    	jnc	di_savehand			; no errors
   436 000000D7 E9(0000)                    jmp NEAR PTR dos_error  ; dos error
   437                                  
   438                                  di_savehand:
   439 000000DA A3[0800]                    mov [ilf_handle],ax       ; save handle of ILF file
   440 000000DD 89C3                        mov bx,ax
   441 000000DF A0[0000]                    mov al,[inc_padval]
   442 000000E2 A2[1E00]                    mov BYTE PTR [tbuff+4],al ; save pad value (one byte for now)
   443 000000E5 A1[0000]                    mov ax,[obj_count]
   444 000000E8 A3[2000]                    mov WORD PTR [tbuff+6],ax ; save object module count
   445 000000EB A1[0000]                    mov ax,[lib_count]
   446 000000EE A3[2200]                    mov WORD PTR [tbuff+8],ax ; save library file count
   447 000000F1 30E4                        xor ah,ah
   448 000000F3 A0[0000]                    mov al,[is_internal]      ; get internal overlays flag
   449 000000F6 08C0                        or  al,al               ; see if set
   450 000000F8 7402                        je  di_ilfbitflag       ; no
   451 000000FA B001                        mov al,1                ; set bit 0 to indicate internal overlays
   452                                  
   453                                  di_ilfbitflag:
   454 000000FC A3[2400]                    mov WORD PTR [tbuff+10],ax    ; save bit flags
   455 000000FF BA[1A00]                    mov dx,OFFSET tbuff wrt DGROUP
   456 00000102 B90C00                      mov cx,12
   457 00000105 B440                        mov ah,40h              ; write file
   458 00000107 CD21                        int 21h
   459 00000109 E8(0000)                    call    restore_ems_map
   460 0000010C 7303E98600                  jc  to_doserr3
   461 00000111 39C8                    	cmp ax, cx
   462 00000113 B82700                  	mov ax, 27h			; insufficient disk space error
   463 00000116 757F                    	jne to_doserr3
   464                                  
   465 00000118 B91400                      mov cx,20
   466 0000011B BA[0000]                    mov dx,OFFSET zero_table wrt DGROUP ; write zero bytes for remainder of control info
   467 0000011E B440                        mov ah,40h              ; write file
   468 00000120 CD21                        int 21h
   469 00000122 E8(0000)                    call    restore_ems_map
   470 00000125 7270                        jc  to_doserr3
   471 00000127 39C8                    	cmp ax, cx
   472 00000129 B82700                  	mov ax, 27h			; insufficient disk space error
   473 0000012C 7569                    	jne to_doserr3
   474                                  
   475                                  di_yexit:
   476 0000012E B059                        mov al,'Y'              ; indicate not to exit link
   477 00000130 C3                          ret
   478                                  
   479                                  di_ilf_found:
   480 00000131 A3[0800]                    mov [ilf_handle],ax       ; save file handle
   481                                  
   482                                  ; check EXE file existence
   483 00000134 BA[0000]                    mov dx,OFFSET exe_name wrt DGROUP
   484 00000137 B80043                      mov ax,4300h            ; get file attributes (check for file existence)
   485 0000013A CD21                        int 21h
   486 0000013C E8(0000)                    call    restore_ems_map
   487 0000013F 7243                        jc  to_inc_bail
   488                                  
   489                                  ; if not internal overlays, and overlays specified, check OVL file existence
   490 00000141 803E[0000]00                cmp byte [is_internal],0       ; see if internal overlays
   491 00000146 7514                        jne di_findend          ; yes
   492 00000148 803E[0000]00                cmp byte [is_anyovls],0        ; see if any overlays
   493 0000014D 740D                        je  di_findend          ; no
   494                                  
   495 0000014F BA[0000]                    mov dx,OFFSET ovl_filename wrt DGROUP
   496 00000152 B80043                      mov ax,4300h            ; get file attributes (check for file existence)
   497 00000155 CD21                        int 21h
   498 00000157 E8(0000)                    call    restore_ems_map
   499 0000015A 7228                        jc  to_inc_bail
   500                                  
   501                                  di_findend:
   502 0000015C 8B1E[0800]                  mov bx,[ilf_handle]
   503 00000160 31C9                        xor cx,cx
   504 00000162 89CA                        mov dx,cx               ; zero hi/low file offset words
   505 00000164 B80242                      mov ax,4202h            ; move file pointer, relative to end of file
   506 00000167 CD21                        int 21h
   507 00000169 E8(0000)                    call    restore_ems_map
   508 0000016C 7229                        jc  to_doserr3          ; error occurred
   509                                  
   510                                  ; convert bytes in dx:ax to paragraphs
   511 0000016E 89C1                        mov cx,ax               ; cx holds low word file char count
   512 00000170 A3[0C00]                    mov [ilf_filesize],ax     ; save file size assuming less than 64K
   513                                  
   514 00000173 83C00F                      add ax,15               ; round up
   515 00000176 83D200                      adc dx,0
   516 00000179 09D2                        or  dx,dx               ; fail if file >64K
   517 0000017B 740A                        je  filesize_ok         ; file <64K
   518                                  
   519                                  ; file is larger than 64K, don't use it
   520 0000017D B43E                        mov ah,3eh              ; close file
   521 0000017F CD21                        int 21h
   522 00000181 E8(0000)                    call    restore_ems_map
   523                                  
   524                                  to_inc_bail:
   525 00000184 E96207                      jmp NEAR PTR inc_bailout    ; fail incremental link
   526                                  
   527                                  filesize_ok:
   528 00000187 D1E8                        shr ax,1                ; /2
   529 00000189 D1E8                        shr ax,1                ; /4
   530 0000018B D1E8                        shr ax,1                ; /8
   531 0000018D D1E8                        shr ax,1                ; /16
   532 0000018F 89C3                        mov bx,ax               ; get number of paragraphs to allocate to read in ILF file
   533 00000191 B448                        mov ah,48h              ; allocate memory
   534 00000193 CD21                        int 21h
   535 00000195 7303                        jnc mem_allocated       ; successful
   536                                  
   537                                  to_doserr3:
   538 00000197 E9(0000)                    jmp NEAR PTR dos_error  ; dos error
   539                                  
   540                                  mem_allocated:
   541 0000019A A3[0600]                    mov [ilf_fileseg],ax      ; save segment of memory holding ILF file
   542                                  
   543                                  ; dx still zero
   544 0000019D 8B1E[0800]                  mov bx,[ilf_handle]
   545 000001A1 31C9                        xor cx,cx
   546 000001A3 B80042                      mov ax,4200h            ; move file pointer from start of file
   547 000001A6 CD21                        int 21h                 ; rewind file
   548 000001A8 E8(0000)                    call    restore_ems_map
   549                                  
   550 000001AB A1[0600]                    mov ax,[ilf_fileseg]      ; get segment of memory holding ILF file image
   551 000001AE 8B0E[0C00]                  mov cx,[ilf_filesize]
   552 000001B2 31D2                        xor dx,dx
   553 000001B4 8CDF                        mov di,ds               ; save data segment
   554 000001B6 8ED8                        mov ds,ax               ; ds:dx -> read buffer area
   555 000001B8 B43F                        mov ah,3fh              ; read file
   556 000001BA CD21                        int 21h
   557 000001BC E8(0000)                    call    restore_ems_map
   558 000001BF 8EDF                        mov ds,di               ; restore ds -> WarpLink data
   559 000001C1 72D4                        jc  to_doserr3
   560 000001C3 39C8                    	cmp ax, cx
   561 000001C5 B8FEFF                  	mov ax, -2		; short read code
   562 000001C8 75CD                    	jne to_doserr3
   563                                  
   564 000001CA B43E                        mov ah,3eh              ; close file
   565 000001CC CD21                        int 21h
   566 000001CE E8(0000)                    call    restore_ems_map
   567 000001D1 72C4                        jc  to_doserr3
   568                                  
   569 000001D3 8E06[0600]                  mov es,[ilf_fileseg]
   570 000001D7 31F6                        xor si,si               ; es:si -> ilf file buffer
   571 000001D9 26AD                        es lodsw   ; get first word of signature
   572 000001DB 3D3130                      cmp ax,'10'             ; see if match
   573 000001DE 7509                        jne to_remem_bailout    ; no
   574 000001E0 26AD                        es lodsw   ; get second word of signature
   575 000001E2 3D3032                      cmp ax,'02'             ; see if match
   576 000001E5 7502                        jne to_remem_bailout    ; no
   577 000001E7 7403                        je  di_getpad           ; yes, continue
   578                                  
   579                                  to_remem_bailout:
   580 000001E9 E9FD00                      jmp NEAR PTR remem_bailout  ; no, invalid ILF
   581                                  
   582                                  di_getpad:
   583 000001EC A1[0000]                    mov ax,[first_objblk_ptr]
   584 000001EF A3[0000]                    mov [obj_block_ptr],ax    ; init current block pointer to first block
   585                                  
   586 000001F2 A1[0000]                    mov ax,[first_libblk_ptr]
   587 000001F5 A3[0000]                    mov [lib_block_ptr],ax     ; init current block pointer to first block
   588                                  
   589 000001F8 26AD                        es lodsw   ; get pad value
   590 000001FA A3[0E00]                    mov [ilf_padval],ax       ; save it
   591 000001FD 26AD                        es lodsw   ; get number of object modules
   592 000001FF 3B06[0000]                  cmp ax,[obj_count]        ; check that matches current count
   593 00000203 75E4                        jne to_remem_bailout    ; no
   594 00000205 26AD                        es lodsw   ; get number of library files
   595 00000207 3B06[0000]                  cmp ax,[lib_count]        ; check that matches current count
   596 0000020B 75DC                        jne to_remem_bailout    ; no
   597                                  
   598 0000020D 26AD                        es lodsw   ; get control info bit flags
   599 0000020F 2401                        and al,1                ; save internal overlays flag
   600 00000211 A2[0000]                    mov [ilf_internal],al
   601 00000214 8CC0                        mov ax,es
   602 00000216 83C002                      add ax,2
   603 00000219 8EC0                        mov es,ax               ; es -> first entry in ilf file
   604 0000021B 31F6                        xor si,si               ; zero offset into file
   605                                  
   606                                  di_entryloop:
   607 0000021D 26AD                        es lodsw   ; get bit flags
   608 0000021F 89C2                        mov dx,ax               ; dx holds bit flags
   609 00000221 F6C480                      test    ah,80h          ; see if end of file
   610 00000224 7403                        je  di_noteof           ; no
   611 00000226 E9E300                      jmp NEAR PTR inc_done   ; yes, done
   612                                  
   613                                  di_noteof:
   614 00000229 89F0                        mov ax,si
   615 0000022B 83C01E                      add ax,30
   616 0000022E 3B06[0C00]                  cmp ax,[ilf_filesize]     ; see if entry past end of file (garbaged file)
   617 00000232 77B5                        ja  to_remem_bailout    ; yes, fail the link
   618                                  
   619 00000234 268B4404                    mov ax,[es:si+4]        ; get object module/library number
   620 00000238 F6C204                      test    dl,4            ; see if library file
   621 0000023B 7511                        jne di_getfilename      ; yes
   622 0000023D 3B06[0C00]                  cmp ax,[prev_obj_number]  ; see if obj/lib matches previous entry's
   623 00000241 A3[0C00]                    mov [prev_obj_number],ax  ; update previous entry
   624 00000244 7508                        jne di_getfilename      ; no, continue
   625 00000246 F6C210                      test    dl,16           ; see if non-Clipper object module
   626 00000249 7503                        jne di_getfilename      ; yes
   627 0000024B E99500                      jmp NEAR PTR next_entry ; yes, ignore this entry (same file, same date/timestamp)
   628                                  
   629                                  di_getfilename:
   630                                  
   631                                  ; ax holds object module/library number
   632 0000024E 56                          push    si              ; save critical registers
   633 0000024F 06                          push    es
   634 00000250 F6C204                      test    dl,4            ; see if library file
   635 00000253 7508                        jne di_inlib
   636                                  
   637                                  ; in object module
   638 00000255 A3[0000]                    mov [current_obj],ax
   639 00000258 E8(0000)                    call    get_curr_obj    ; get object module name in filename
   640 0000025B EB15                        jmp SHORT di_havename
   641                                  
   642                                  ; in library
   643                                  di_inlib:
   644 0000025D 89C1                        mov cx,ax               ; save current library count in cx
   645                                  
   646                                  di_libloop:
   647 0000025F A1[1400]                    mov ax,[lastused_lib]
   648 00000262 40                          inc ax
   649 00000263 A3[1400]                    mov [lastused_lib],ax     ; bump count of library name last used
   650 00000266 A3[0000]                    mov [current_lib],ax      ; use as current library
   651 00000269 E8(0000)                    call    get_curr_lib    ; get library name in filename
   652 0000026C 3B0E[1400]                  cmp cx,[lastused_lib]     ; see if last name matches current library
   653 00000270 75ED                        jne di_libloop          ; no, get another name
   654                                  
   655                                  di_havename:
   656 00000272 07                          pop es                  ; restore critical registers
   657 00000273 5E                          pop si
   658                                  
   659                                  ; object module or library entry in ilf file
   660 00000274 89D3                        mov bx,dx               ; save bit flags in bx
   661 00000276 BA[0000]                    mov dx,OFFSET filename wrt DGROUP
   662 00000279 89D7                        mov di,dx
   663 0000027B B80043                      mov ax,4300h            ; get file attributes (check for file existence)
   664 0000027E CD21                        int 21h
   665 00000280 E8(0000)                    call    restore_ems_map
   666 00000283 89DA                        mov dx,bx               ; restore bit flags in dx
   667 00000285 7313                        jnc di_foundfile        ; file found okay
   668 00000287 E8(0000)                	call	file_not_found	; check for file not found errors
   669                                  
   670                                  ; object module or library not in current directory
   671                                  di_findfile:
   672 0000028A F6C204                      test    dl,4            ; see if library file
   673 0000028D 7405                        je  di_searchobj        ; no
   674                                  
   675 0000028F BB[0000]                    mov bx,OFFSET libtext wrt DGROUP    ; bx -> LIB string for environment searches
   676 00000292 EB03                        jmp SHORT di_searchenv  ; search environment strings for file
   677                                  
   678                                  di_searchobj:
   679 00000294 BB[0000]                    mov bx,OFFSET objtext wrt DGROUP    ; bx -> OBJ string for environment searches
   680                                  
   681                                  di_searchenv:
   682 00000297 E8(0000)                    call    check_libobj_path   ; try to find file
   683                                  
   684                                  ; di -> file name, including any pathspec
   685                                  ; dx holds bit flags
   686                                  di_foundfile:
   687 0000029A 52                          push    dx              ; save bit flags
   688 0000029B 89FA                        mov dx,di
   689 0000029D B8003D                      mov ax,3d00h            ; open with read access
   690 000002A0 CD21                        int 21h
   691 000002A2 E8(0000)                    call    restore_ems_map
   692 000002A5 7303                    	jnc	di_savehand2
   693 000002A7 E9(0000)                    jmp NEAR PTR dos_error
   694                                  
   695                                  di_savehand2:
   696 000002AA A3[0800]                    mov [ilf_handle],ax
   697 000002AD 89C3                        mov bx,ax
   698 000002AF B80057                      mov ax,5700h            ; get file date and time
   699 000002B2 CD21                        int 21h
   700 000002B4 E8(0000)                    call    restore_ems_map
   701 000002B7 727D                        jc  to_doserr2
   702                                  
   703 000002B9 B43E                        mov ah,3eh              ; close file
   704 000002BB CD21                        int 21h
   705 000002BD E8(0000)                    call    restore_ems_map
   706                                  
   707 000002C0 5B                          pop bx                  ; get bit flags in bx
   708 000002C1 F6C304                      test    bl,4            ; see if library file
   709 000002C4 740D                        je  di_2                ; no
   710                                  
   711                                  ; library or non-Clipper object module, date/timestamp cannot change
   712                                  di_cantchange:
   713 000002C6 263B14                      cmp dx,[es:si]          ; see if date has changed
   714 000002C9 751E                        jne remem_bailout       ; yes
   715 000002CB 263B4C02                    cmp cx,[es:si+2]        ; see if time has changed
   716 000002CF 7518                        jne remem_bailout       ; yes
   717 000002D1 EB10                        jmp NEAR PTR next_entry ; no change, try next entry
   718                                  
   719                                  di_2:
   720 000002D3 F6C310                      test    bl,16           ; see if non-Clipper object module
   721 000002D6 75EE                        jne di_cantchange       ; yes
   722                                  
   723                                  ; Clipper object module, see if it has changed
   724 000002D8 263B14                      cmp dx,[es:si]          ; see if date has changed
   725 000002DB 7517                        jne modified_obj        ; yes
   726 000002DD 263B4C02                    cmp cx,[es:si+2]        ; see if time has changed
   727 000002E1 7511                        jne modified_obj        ; yes
   728                                  
   729                                  ; move to next entry in ILF file
   730                                  next_entry:
   731 000002E3 83C61E                      add si,30               ; si-> next entry
   732 000002E6 E934FF                      jmp NEAR PTR di_entryloop   ; loop back for next entry
   733                                  
   734                                  remem_bailout:
   735 000002E9 8B1E[0600]                  mov bx,[ilf_fileseg]      ; get memory segment allocated to hold ILF file
   736 000002ED B449                        mov ah,49h              ; release memory
   737 000002EF CD21                        int 21h
   738 000002F1 E9F505                      jmp NEAR PTR inc_bailout
   739                                  
   740                                  ; Clipper object module has had the date and/or timestamp changed
   741                                  ; check if should put in new info
   742                                  modified_obj:
   743 000002F4 268914                      mov [es:si],dx          ; update file date entry
   744 000002F7 26894C02                    mov [es:si+2],cx        ; update file time entry
   745 000002FB E87200                      call    check_modified
   746 000002FE 08C0                        or  al,al               ; see if should bailout
   747 00000300 75E7                        jne remem_bailout       ; yes
   748 00000302 8B36[1200]                  mov si,[entry_end]        ; si-> first entry after last entry of previous object module
   749 00000306 83EE02                      sub si,2                ; adjust back to start of entry
   750 00000309 E911FF                      jmp NEAR PTR di_entryloop
   751                                  
   752                                  inc_done:
   753 0000030C 833E[0A00]00                cmp word [change_flag],0       ; see if any changes occurred
   754 00000311 7516                        jne yes_change          ; yes
   755                                  
   756                                  ; no changes occurred in EXE file, give feedback
   757 00000313 BB[6200]                    mov bx,OFFSET nochange_text wrt DGROUP
   758 00000316 8A4FFF                      mov cl,[bx-1]           ; get length of string to print
   759 00000319 30ED                        xor ch,ch
   760 0000031B 89DA                        mov dx,bx               ; ds:dx -> string
   761 0000031D BB0100                      mov bx,STDOUT           ; standard output
   762 00000320 B440                        mov ah,40h              ; write to device
   763 00000322 CD21                        int 21h
   764 00000324 E8(0000)                    call    restore_ems_map
   765 00000327 EB3C                        jmp SHORT inc_exit
   766                                  
   767                                  yes_change:
   768 00000329 BA[4200]                    mov dx,OFFSET ilf_name wrt DGROUP   ; ds:dx -> filespec
   769 0000032C B8013D                      mov ax,3d01h            ; open file for writing
   770 0000032F CD21                        int 21h
   771 00000331 E8(0000)                    call    restore_ems_map
   772 00000334 7303                        jnc okay_open
   773                                  
   774                                  to_doserr2:
   775 00000336 E9(0000)                    jmp NEAR PTR dos_error
   776                                  
   777                                  okay_open:
   778 00000339 A1[0600]                    mov ax,[ilf_fileseg]      ; get segment of memory holding ILF file image
   779 0000033C 8B1E[0800]                  mov bx,[ilf_handle]
   780 00000340 8B0E[0C00]                  mov cx,[ilf_filesize]
   781 00000344 31D2                        xor dx,dx
   782 00000346 8CDF                        mov di,ds               ; save data segment
   783 00000348 8ED8                        mov ds,ax               ; ds:dx -> write buffer area
   784 0000034A B440                        mov ah,40h              ; write file
   785 0000034C CD21                        int 21h
   786 0000034E E8(0000)                    call    restore_ems_map
   787 00000351 8EDF                        mov ds,di               ; restore ds -> WarpLink data
   788 00000353 72E1                        jc  to_doserr2
   789 00000355 39C8                    	cmp ax, cx
   790 00000357 B82700                  	mov ax, 27h			; insufficient disk space error
   791 0000035A 75DA                    	jne to_doserr2
   792                                  
   793 0000035C B43E                        mov ah,3eh              ; close file
   794 0000035E CD21                        int 21h
   795 00000360 E8(0000)                    call    restore_ems_map
   796 00000363 72D1                        jc  to_doserr2
   797                                  
   798                                  inc_exit:
   799 00000365 8B1E[0600]                  mov bx,[ilf_fileseg]      ; get memory segment allocated to hold ILF file
   800 00000369 B449                        mov ah,49h              ; release memory
   801 0000036B CD21                        int 21h
   802 0000036D B04E                        mov al,'N'              ; indicate to exit link
   803 0000036F C3                          ret
   804                                  
   805                                  do_incremental  ENDP
   806                                  
   807                                  ;*****************************
   808                                  ;* CHECK_MODIFIED            *
   809                                  ;*****************************
   810                                  
   811                                  ; assume Clipper object module with new date/timestamp has been
   812                                  ; modified, and update EXE file if possible.
   813                                  ; if not possible (non-code segment change) transfer to bailout routine
   814                                  ; upon entry es:si-> 2nd word of first entry of modified object module
   815                                  ; bx holds the entry's bit flags
   816                                  ; destroys ax,bx,cx,dx,di
   817                                  ; returns al==0 if okay to continue, nonzero if should bailout
   818                                  ; updates si to first entry after those of object module
   819                                  
   820                                  check_modified  PROC
   821 00000370 8936[1000]                  mov [entry_start],si      ; save first entry of object module
   822 00000374 89F2                        mov dx,si               ; save first entry pointer
   823                                  
   824                                  cm_loop:
   825 00000376 268B44FE                    mov ax,[es:si-2]        ; get bit flags of this entry
   826 0000037A 80E480                      and ah,80h              ; see if end of file
   827 0000037D 750F                        jne cm_segdone          ; yes, all object module entries found
   828 0000037F 268B4404                    mov ax,[es:si+4]        ; get object module number of entry
   829 00000383 3B06[0C00]                  cmp ax,[prev_obj_number]  ; see if it matches previous entry
   830 00000387 7505                        jne cm_segdone          ; no, all object module entries found
   831 00000389 83C620                      add si,32               ; move to next entry of object module
   832 0000038C EBE8                        jmp SHORT cm_loop       ; loop until found final object module entry
   833                                  
   834                                  cm_segdone:
   835 0000038E 8936[1200]                  mov [entry_end],si        ; save entry after last entry of object module
   836                                  
   837 00000392 31C0                        xor ax,ax
   838 00000394 A3[3400]                    mov WORD PTR [prev_fileoff],ax    ; init previous file offset
   839 00000397 A3[3600]                    mov WORD PTR [prev_fileoff+2],ax
   840                                  
   841 0000039A A3[1400]                    mov [ilf_lnames],ax       ; init current lnames index
   842 0000039D A3[1A00]                    mov [ilf_segdef],ax       ; init current segdef index
   843                                  
   844 000003A0 A3[0000]                    mov [ovl_handle],ax       ; init handles used for ovl/exe/ilf files
   845 000003A3 A3[0000]                    mov [map_handle],ax
   846                                  
   847 000003A6 BF[0000]                    mov di,OFFSET inc_seg_clcode wrt DGROUP
   848 000003A9 8CC3                        mov bx,es               ; save -> object module image
   849 000003AB 8CD9                        mov cx,ds
   850 000003AD 8EC1                        mov es,cx               ; es -> WarpLink data
   851 000003AF B90001                      mov cx,256              ; zero init inc_seg_clcode array of 512 bytes
   852 000003B2 F3AB                        rep stosw
   853 000003B4 8EC3                        mov es,bx               ; restore es -> object module image
   854                                  
   855 000003B6 BA[0000]                    mov dx,OFFSET filename wrt DGROUP   ; ds:dx -> obj filespec
   856 000003B9 B8003D                      mov ax,3d00h            ; open file for reading
   857 000003BC CD21                        int 21h
   858 000003BE E8(0000)                    call    restore_ems_map
   859 000003C1 7303                        jnc cm_3                ; file found okay
   860                                  
   861                                  cm_doserr:
   862 000003C3 E9(0000)                    jmp NEAR PTR dos_error
   863                                  
   864                                  cm_3:
   865 000003C6 A3[0000]                    mov [image_handle],ax     ; save file handle
   866                                  
   867                                  ; allocate enough memory to read some object file records into memory (32K)
   868 000003C9 BB0008                      mov bx,2048
   869 000003CC B448                        mov ah,48h              ; allocate memory
   870 000003CE CD21                        int 21h
   871 000003D0 72F1                        jc  cm_doserr
   872                                  
   873 000003D2 A3[0800]                    mov [obj_fileseg],ax      ; save segment of object file image
   874                                  
   875                                  ; allocate enough memory to hold symbols (3F0H)
   876 000003D5 BB3F00                      mov bx,3fh
   877 000003D8 B448                        mov ah,48h              ; allocate memory
   878 000003DA CD21                        int 21h
   879 000003DC 72E5                        jc  cm_doserr
   880 000003DE A3[0A00]                    mov [symbols_buff],ax     ; save segment of symbols buffer
   881                                  
   882                                  ; read all or part of object file into memory
   883                                  cm_readloop:
   884 000003E1 A1[0800]                    mov ax,[obj_fileseg]      ; get segment of memory holding object file image
   885 000003E4 8B1E[0000]                  mov bx,[image_handle]
   886 000003E8 B90080                      mov cx,8000h
   887 000003EB 31D2                        xor dx,dx
   888 000003ED 8CDF                        mov di,ds               ; save data segment
   889 000003EF 8ED8                        mov ds,ax               ; ds:dx -> read buffer area
   890 000003F1 B43F                        mov ah,3fh              ; read file (no short read error ?)
   891 000003F3 CD21                        int 21h
   892 000003F5 E8(0000)                    call    restore_ems_map
   893 000003F8 8EDF                        mov ds,di               ; restore ds -> WarpLink data
   894 000003FA 72C7                        jc  cm_doserr
   895                                  
   896                                  ; parse through object file image, looking for SEGDEF and LEDATA records,
   897                                  ; stop when hit MODEND record
   898 000003FC 8E06[0800]                  mov es,[obj_fileseg]
   899 00000400 31F6                        xor si,si
   900                                  
   901                                  cm_parseloop:
   902 00000402 26AC                        es lodsb   ; get object record
   903 00000404 88C2                        mov dl,al
   904 00000406 26AD                        es lodsw   ; get length of record
   905 00000408 89C1                        mov cx,ax
   906 0000040A 81F90010                    cmp cx,4096             ; check if record length is >=4K
   907 0000040E 731A                        jae cm_remem            ; yes, restore 32K memory, then bailout
   908 00000410 80FA98                      cmp dl,SEGDEF
   909 00000413 7509                        jne cm_chkledata
   910 00000415 E82C01                      call    inc_segdef
   911 00000418 08C0                        or  al,al               ; see if should bailout
   912 0000041A 747D                        je  cm_nextrec          ; no
   913 0000041C EB0C                        jmp SHORT cm_remem      ; yes
   914                                  
   915                                  cm_chkledata:
   916 0000041E 80FAA0                      cmp dl,LEDATA
   917 00000421 751A                        jne cm_chklnames
   918 00000423 E8D501                      call    inc_ledata
   919 00000426 08C0                        or  al,al               ; see if should bailout
   920 00000428 746F                        je  cm_nextrec          ; no
   921                                  
   922                                  cm_remem:
   923 0000042A 8B1E[0A00]                  mov bx,[symbols_buff]     ; get segment of memory allocated to hold symbols
   924 0000042E B449                        mov ah,49h              ; release memory
   925 00000430 CD21                        int 21h
   926                                  
   927 00000432 8B1E[0800]                  mov bx,[obj_fileseg]      ; get memory segment allocated to hold object file
   928 00000436 B449                        mov ah,49h              ; release memory
   929 00000438 CD21                        int 21h
   930 0000043A B001                        mov al,1                ; flag should bailout of incremental link
   931 0000043C C3                          ret
   932                                  
   933                                  cm_chklnames:
   934 0000043D 80FA96                      cmp dl,LNAMES
   935 00000440 7505                        jne cm_chkmodend
   936 00000442 E87F00                      call    inc_lnames
   937 00000445 EB52                        jmp SHORT cm_nextrec
   938                                  
   939                                  cm_chkmodend:
   940 00000447 80FA8A                      cmp dl,MODEND
   941 0000044A 754D                        jne cm_nextrec
   942                                  
   943                                  ; MODEND, close the open exe and ovl file, if exists.  Close object file.
   944 0000044C 8B1E[0000]                  mov bx,[map_handle]       ; get exe file handle (yes, in map_handle)
   945 00000450 B43E                        mov ah,3eh              ; close file
   946 00000452 CD21                        int 21h
   947 00000454 E8(0000)                    call    restore_ems_map
   948                                  
   949 00000457 803E[0000]00                cmp byte [ilf_internal],0      ; see if internal overlays
   950 0000045C 7512                        jne cm_closeobj         ; yes
   951 0000045E 803E[0000]00                cmp byte [is_anyovls],0        ; see if any overlays
   952 00000463 740B                        je  cm_closeobj         ; no
   953                                  
   954 00000465 8B1E[0000]                  mov bx,[ovl_handle]       ; get overlay file handle
   955 00000469 B43E                        mov ah,3eh              ; close file
   956 0000046B CD21                        int 21h
   957 0000046D E8(0000)                    call    restore_ems_map
   958                                  
   959                                  cm_closeobj:
   960 00000470 8B1E[0000]                  mov bx,[image_handle]     ; get object module handle (yes, in image_handle)
   961 00000474 B43E                        mov ah,3eh              ; close file
   962 00000476 CD21                        int 21h
   963 00000478 E8(0000)                    call    restore_ems_map
   964                                  
   965 0000047B 8B1E[0800]                  mov bx,[obj_fileseg]      ; get memory segment allocated to hold object file
   966 0000047F B449                        mov ah,49h              ; release memory
   967 00000481 CD21                        int 21h
   968                                  
   969 00000483 8B1E[0A00]                  mov bx,[symbols_buff]     ; get segment of memory allocated to hold symbols
   970 00000487 B449                        mov ah,49h              ; release memory
   971 00000489 CD21                        int 21h
   972                                  
   973 0000048B 8E06[0600]                  mov es,[ilf_fileseg]      ; restore es->ilf file image
   974 0000048F 8CC0                        mov ax,es
   975 00000491 83C002                      add ax,2
   976 00000494 8EC0                        mov es,ax               ; es -> first entry in ilf file
   977 00000496 30C0                        xor al,al               ; flag to continue incremental link
   978 00000498 C3                          ret
   979                                  
   980                                  ; move to next record
   981                                  cm_nextrec:
   982 00000499 01CE                        add si,cx               ; position to next record
   983 0000049B 81FE0070                    cmp si,7000h            ; see if at 28K position
   984 0000049F 7703                        ja  cm_at28k            ; yes
   985 000004A1 E95EFF                      jmp NEAR PTR cm_parseloop   ; no
   986                                  
   987                                  ; at or past 28K position, seek file to si+previous offset, zero si, read in more of file
   988                                  cm_at28k:
   989 000004A4 0136[3400]                  add WORD PTR [prev_fileoff],si    ; update file offset
   990 000004A8 8316[3600]00                adc WORD [prev_fileoff+2],0
   991 000004AD 8B16[3400]                  mov dx,WORD PTR [prev_fileoff]
   992 000004B1 8B0E[3600]                  mov cx,WORD PTR [prev_fileoff+2]  ; cx:dx hold file offset to seek to
   993 000004B5 8B1E[0000]                  mov bx,[image_handle]
   994 000004B9 B80042                      mov ax,4200h            ; move file pointer from start of file
   995 000004BC CD21                        int 21h
   996 000004BE E8(0000)                    call    restore_ems_map
   997 000004C1 E91DFF                      jmp NEAR PTR cm_readloop
   998                                  
   999                                  check_modified  ENDP
  1000                                  
  1001                                  ;*****************************
  1002                                  ;* INC_LNAMES                *
  1003                                  ;*****************************
  1004                                  
  1005                                  ; track all lname indices of class 'CODE'
  1006                                  ; use nonzero value in inc_seg_clcode array
  1007                                  ; es:si -> first entry, cx holds record length
  1008                                  ; destroys ax,bx,dx
  1009                                  ; updates si,cx
  1010                                  
  1011                                  inc_lnames  PROC
  1012                                  
  1013                                  il_loop:
  1014 000004C4 83F901                      cmp cx,1                ; see if at end of record
  1015 000004C7 767A                        jbe il_ret              ; yes
  1016                                  
  1017                                  ; check for class 'CODE', prefixed with length of 4
  1018 000004C9 268A04                      mov al,[es:si]
  1019 000004CC 3C04                        cmp al,4
  1020 000004CE 7528                        jne il_notcode
  1021 000004D0 26807C0143                  cmp BYTE PTR [es:si+1],'C'
  1022 000004D5 7521                        jne il_notcode
  1023 000004D7 26807C024F                  cmp BYTE PTR [es:si+2],'O'
  1024 000004DC 751A                        jne il_notcode
  1025 000004DE 26807C0344                  cmp BYTE PTR [es:si+3],'D'
  1026 000004E3 7513                        jne il_notcode
  1027 000004E5 26807C0445                  cmp BYTE PTR [es:si+4],'E'
  1028 000004EA 750C                        jne il_notcode
  1029                                  
  1030                                  ; a match, save it
  1031 000004EC 8B1E[1400]                  mov bx,[ilf_lnames]       ; get current lnames index
  1032 000004F0 81C3[0000]                  add bx,OFFSET inc_seg_clcode wrt DGROUP ; add in array base
  1033 000004F4 8807                        mov [bx],al             ; make array element nonzero to flag class 'CODE'
  1034 000004F6 EB3D                        jmp SHORT il_next
  1035                                  
  1036                                  ; not code class, see if 'SYMBOLS'
  1037                                  il_notcode:
  1038 000004F8 3C07                        cmp al,7
  1039 000004FA 7539                        jne il_next
  1040 000004FC 26807C0153                  cmp BYTE PTR [es:si+1],'S'
  1041 00000501 7532                        jne il_next
  1042 00000503 26807C0259                  cmp BYTE PTR [es:si+2],'Y'
  1043 00000508 752B                        jne il_next
  1044 0000050A 26807C034D                  cmp BYTE PTR [es:si+3],'M'
  1045 0000050F 7524                        jne il_next
  1046 00000511 26807C0442                  cmp BYTE PTR [es:si+4],'B'
  1047 00000516 751D                        jne il_next
  1048 00000518 26807C054F                  cmp BYTE PTR [es:si+5],'O'
  1049 0000051D 7516                        jne il_next
  1050 0000051F 26807C064C                  cmp BYTE PTR [es:si+6],'L'
  1051 00000524 750F                        jne il_next
  1052 00000526 26807C0753                  cmp BYTE PTR [es:si+7],'S'
  1053 0000052B 7508                        jne il_next
  1054 0000052D 8B1E[1400]                  mov bx,[ilf_lnames]       ; get current lnames index
  1055 00000531 891E[1600]                  mov [sym_lnames],bx       ; save lnames index of symbols class segment
  1056                                  
  1057                                  ; al holds entry length
  1058                                  il_next:
  1059 00000535 FEC0                        inc al                  ; adjust for length byte
  1060 00000537 30E4                        xor ah,ah               ; zap high byte
  1061 00000539 01C6                        add si,ax               ; compute start of next lnames
  1062 0000053B 29C1                        sub cx,ax               ; adjust record length left
  1063 0000053D FF06[1400]                  inc word [ilf_lnames]          ; bump lnames index
  1064 00000541 EB81                        jmp SHORT il_loop       ; loop back for next lnames entry
  1065                                  
  1066                                  il_ret:
  1067 00000543 C3                          ret
  1068                                  inc_lnames  ENDP
  1069                                  
  1070                                  ;*****************************
  1071                                  ;* INC_SEGDEF                *
  1072                                  ;*****************************
  1073                                  
  1074                                  ; SEGDEF record, check if changed and changeable, if so find corresponding
  1075                                  ; entry in ilf file image.  Check if new size <= old size (old size has padval added)
  1076                                  ; if not, bailout
  1077                                  ; returns al==0 if okay to continue, nonzero if should bailout
  1078                                  ; destroys ax,bx,dx,di
  1079                                  ; updates si,cx
  1080                                  
  1081                                  inc_segdef  PROC
  1082 00000544 83F901                      cmp cx,1                ; see if null segdef record
  1083 00000547 7703                        ja iseg_2               ; no
  1084                                  
  1085 00000549 30C0                        xor al,al               ; indicate okay to continue
  1086 0000054B C3                          ret
  1087                                  
  1088                                  iseg_2:
  1089 0000054C 26AC                        es lodsb   ; get ACBP byte
  1090 0000054E 49                          dec cx                  ; drop count of bytes remaining in record
  1091 0000054F 24E0                        and al,0e0h             ; mask off all but align field
  1092 00000551 7506                        jne iseg_noabs          ; not absolute segment, no frame number field
  1093 00000553 83E903                      sub cx,3                ; adjust 3 bytes for frame number word, offset byte
  1094 00000556 83C603                      add si,3
  1095                                  
  1096                                  ; es:si -> segment length
  1097                                  iseg_noabs:
  1098 00000559 26AD                        es lodsw   ; get segment length
  1099 0000055B 83E902                      sub cx,2                ; drop record byte count
  1100 0000055E 09C0                        or  ax,ax               ; see if zero length
  1101 00000560 7507                        jne iseg_notzero        ; no
  1102                                  
  1103                                  ; zero length segments are ignored
  1104                                  iseg_ok:
  1105 00000562 FF06[1A00]                  inc word [ilf_segdef]          ; bump segdef index
  1106 00000566 30C0                        xor al,al               ; indicate okay to continue
  1107 00000568 C3                          ret
  1108                                  
  1109                                  ; get segment name index
  1110                                  iseg_notzero:
  1111 00000569 268A14                      mov dl,[es:si]          ; get low byte of segment name index
  1112 0000056C 46                          inc si
  1113 0000056D 49                          dec cx                  ; decrement record length to parse
  1114 0000056E 80FA80                      cmp dl,80h              ; check if more than one byte index value
  1115 00000571 7202                        jb  iseg_3              ; no, continue
  1116 00000573 46                          inc si                  ; go past index second byte
  1117 00000574 49                          dec cx                  ; decrement record length to parse
  1118                                  
  1119                                  ; get class name index
  1120                                  iseg_3:
  1121 00000575 30F6                        xor dh,dh               ; zap high byte of index
  1122 00000577 268A14                      mov dl,[es:si]          ; get low byte of class name index
  1123 0000057A 46                          inc si
  1124 0000057B 49                          dec cx                  ; decrement record length to parse
  1125 0000057C 80FA80                      cmp dl,80h              ; check if more than one byte index value
  1126 0000057F 720A                        jb  iseg_4              ; no, continue
  1127 00000581 80E27F                      and dl,7fh              ; mask off high bit
  1128 00000584 88D6                        mov dh,dl               ; transfer to high word
  1129 00000586 268A14                      mov dl,[es:si]          ; get second byte, actual value
  1130 00000589 46                          inc si
  1131 0000058A 49                          dec cx                  ; decrement record length to parse
  1132                                  
  1133                                  ; dx holds class name index, ax holds segment length
  1134                                  iseg_4:
  1135 0000058B 4A                          dec dx                  ; make class name index relative zero
  1136 0000058C 56                          push    si              ; save si -> segdef record overlay name index
  1137 0000058D 8B1E[0600]                  mov bx,[ilf_fileseg]
  1138 00000591 83C302                      add bx,2
  1139 00000594 8EC3                        mov es,bx               ; es -> first ilf entry
  1140 00000596 8B36[1000]                  mov si,[entry_start]      ; es:si -> ilf file image first entry for object file
  1141                                  
  1142                                  iseg_searchloop:
  1143 0000059A 268B5C14                    mov bx,[es:si+20]       ; bx holds segment index (remember si starts at offset two from base)
  1144 0000059E 3B1E[1A00]                  cmp bx,[ilf_segdef]       ; see if segment indices match
  1145 000005A2 740D                        je  iseg_segmatch       ; yes
  1146 000005A4 83C620                      add si,32               ; move to next entry
  1147 000005A7 3B36[1200]                  cmp si,[entry_end]        ; make sure haven't shot past last entry
  1148 000005AB 72ED                        jb  iseg_searchloop     ; no
  1149                                  
  1150                                  ; segment index not found, bailout
  1151 000005AD 5E                          pop si                  ; restore stack
  1152                                  
  1153                                  iseg_bailout:
  1154 000005AE B001                        mov al,1                ; indicate bailout of incremental link
  1155 000005B0 C3                          ret
  1156                                  
  1157                                  ; found proper entry, get segment length
  1158                                  iseg_segmatch:
  1159 000005B1 268B5C16                    mov bx,[es:si+22]       ; bx holds segment length
  1160 000005B5 268364FEFC                  and WORD PTR [es:si-2],0fffch   ; clear changeable/SYMBOLS bit
  1161                                  
  1162 000005BA BF[0000]                    mov di,OFFSET inc_seg_clcode wrt DGROUP ; di-> array base
  1163 000005BD 01D7                        add di,dx               ; add in class name index
  1164                                  
  1165 000005BF 3B16[1600]                  cmp dx,[sym_lnames]       ; see if SYMBOLS segment, class is SYMBOLS
  1166 000005C3 7514                        jne iseg_notsymseg      ; no
  1167 000005C5 8B16[1A00]                  mov dx,[ilf_segdef]       ; get current segdef index
  1168 000005C9 8916[1800]                  mov [sym_segdef],dx       ; save as SYMBOLS segment index
  1169 000005CD 26834CFE02                  or  WORD PTR [es:si-2],2    ; set SYMBOLS bit
  1170                                  
  1171                                  ; start 04/14/91 code
  1172 000005D2 5E                          pop si                  ; restore si -> segdef record class name index
  1173 000005D3 8E06[0800]                  mov es,[obj_fileseg]      ; restore es-> object file image
  1174 000005D7 EB14                        jmp SHORT iseg_lenchk   ; bypass other segment checks
  1175                                  ; end 04/14/91 code
  1176                                  
  1177                                  iseg_notsymseg:
  1178 000005D9 803D00                      cmp BYTE PTR [di],0     ; see if class 'CODE' or not
  1179 000005DC 7405                        je  iseg_5              ; not
  1180                                  
  1181 000005DE 26834CFE01                  or  WORD PTR [es:si-2],1    ; set changeable bit
  1182                                  
  1183                                  iseg_5:
  1184 000005E3 5E                          pop si                  ; restore si -> segdef record class name index
  1185 000005E4 8E06[0800]                  mov es,[obj_fileseg]      ; restore es-> object file image
  1186                                  
  1187 000005E8 803D00                      cmp BYTE PTR [di],0     ; see if class 'CODE' or not
  1188 000005EB 7407                        je  len_exact           ; not class 'CODE', segment lengths must match exactly
  1189                                  
  1190                                  ; class 'CODE' segment, new segment length in ax must be <= old segment length
  1191                                  ; OR class 'SYMBOLS' segment, same rule applies
  1192                                  iseg_lenchk:
  1193 000005ED 39D8                        cmp ax,bx
  1194 000005EF 77BD                        ja  iseg_bailout        ; new segment is bigger than old segment length plus pad value
  1195 000005F1 E96EFF                      jmp NEAR PTR iseg_ok
  1196                                  
  1197                                  ; not class 'CODE' segment, new segment length in ax must match old in bx
  1198                                  len_exact:
  1199 000005F4 39D8                        cmp ax,bx               ; see if segment lengths match
  1200 000005F6 75B6                        jne iseg_bailout        ; no
  1201 000005F8 E967FF                      jmp NEAR PTR iseg_ok    ; yes, this segdef is okay
  1202                                  
  1203                                  inc_segdef  ENDP
  1204                                  
  1205                                  ;*****************************
  1206                                  ;* INC_LEDATA                *
  1207                                  ;*****************************
  1208                                  
  1209                                  ; LEDATA record, check if CODE/SYMBOLS class, if so either open exe or ovl file
  1210                                  ; (if not open), find ilf_file image entry of owning segdef, seek to proper
  1211                                  ; location in exe/ovl file and write in new info.  If CODE class, adjust past
  1212                                  ; fixup offset if offset zero (first LEDATA of segment).
  1213                                  ; returns al==0 if okay to continue, nonzero if should bailout
  1214                                  ; destroys ax,bx,dx,di
  1215                                  ; updates si,cx
  1216                                  
  1217                                  inc_ledata  PROC
  1218                                  
  1219                                  ; get segment index in dx
  1220 000005FB 30F6                        xor dh,dh               ; zap high byte of index
  1221 000005FD 268A14                      mov dl,[es:si]          ; get low byte of segment index
  1222 00000600 46                          inc si
  1223 00000601 49                          dec cx                  ; decrement record length to parse
  1224 00000602 80FA80                      cmp dl,80h              ; check if more than one byte index value
  1225 00000605 720A                        jb  iled_2              ; no, continue
  1226 00000607 80E27F                      and dl,7fh              ; mask off high bit
  1227 0000060A 88D6                        mov dh,dl               ; transfer to high word
  1228 0000060C 268A14                      mov dl,[es:si]          ; get second byte, actual value
  1229 0000060F 46                          inc si
  1230 00000610 49                          dec cx                  ; decrement record length to parse
  1231                                  
  1232                                  ; find segment entry
  1233                                  iled_2:
  1234 00000611 4A                          dec dx                  ; make segment index relative zero
  1235 00000612 56                          push    si              ; save si -> data
  1236 00000613 A1[0600]                    mov ax,[ilf_fileseg]
  1237 00000616 83C002                      add ax,2
  1238 00000619 8EC0                        mov es,ax               ; es -> first ilf entry
  1239 0000061B 8B36[1000]                  mov si,[entry_start]      ; es:si -> ilf file image first entry for object file
  1240                                  
  1241                                  iled_searchloop:
  1242 0000061F 268B5C14                    mov bx,[es:si+20]       ; bx holds segment index (remember si starts at offset two from base)
  1243 00000623 39D3                        cmp bx,dx               ; see if segment indices match
  1244 00000625 740D                        je  iled_segmatch       ; yes
  1245 00000627 83C620                      add si,32               ; move to next entry
  1246 0000062A 3B36[1200]                  cmp si,[entry_end]        ; make sure haven't shot past last entry
  1247 0000062E 72EF                        jb  iled_searchloop     ; no
  1248                                  
  1249                                  ; segment index not found, bailout
  1250                                  iled_bailout:
  1251 00000630 5E                          pop si                  ; restore stack
  1252 00000631 B001                        mov al,1                ; indicate bailout of incremental link
  1253 00000633 C3                          ret
  1254                                  
  1255                                  ; found proper entry, check if changeable, if not, don't write any bytes
  1256                                  iled_segmatch:
  1257 00000634 30C0                        xor al,al
  1258 00000636 A2[0200]                    mov [symseg_flag],al      ; init SYMBOLS segment flag
  1259 00000639 268B44FE                    mov ax,[es:si-2]        ; get segment bit flags
  1260 0000063D A801                        test    al,1            ; see if segment is changeable (CODE)
  1261 0000063F 7511                        jne iled_canchange      ; yes
  1262                                  
  1263                                  ; check if SYMBOLS segment, perform symbol table update if possible
  1264 00000641 A802                        test    al,2            ; see if SYMBOLS segment
  1265 00000643 7405                        je  iled_nochange       ; no, can't modify segment bytes
  1266 00000645 A2[0200]                    mov [symseg_flag],al      ; yes, set SYMBOLS segment flag
  1267 00000648 EB08                        jmp SHORT iled_canchange
  1268                                  
  1269                                  ; LEDATA segment not changeable, don't write any bytes
  1270                                  iled_nochange:
  1271 0000064A 5E                          pop si                  ; restore stack
  1272 0000064B 8E06[0800]                  mov es,[obj_fileseg]      ; restore es-> object file image
  1273 0000064F 30C0                        xor al,al               ; indicate to continue with incremental link
  1274 00000651 C3                          ret
  1275                                  
  1276                                  ; read the file pointer for start of data bytes
  1277                                  iled_canchange:
  1278 00000652 268B5418                    mov dx,[es:si+24]       ; get low word of file offset pointer
  1279 00000656 268B7C1A                    mov di,[es:si+26]       ; get high word/overlay number
  1280                                  
  1281 0000065A 5E                          pop si                  ; restore si -> data
  1282 0000065B 8E06[0800]                  mov es,[obj_fileseg]      ; restore es-> object file image
  1283                                  
  1284 0000065F 51                          push    cx              ; save count of bytes left in record
  1285                                  
  1286                                  ; check if need to open exe/ovl file
  1287 00000660 52                          push    dx              ; save low word of code offset
  1288 00000661 2408                        and al,8                ; mask off all but in overlay flag
  1289 00000663 A2[0200]                    mov [ilf_inovl],al        ; save overlay status
  1290 00000666 833E[0000]00                cmp word [map_handle],0        ; see if EXE file open
  1291 0000066B 754F                        jne startseek           ; yes, already opened
  1292 0000066D C706[0A00]0100              mov word [change_flag],1       ; flag that EXE was modified
  1293                                  
  1294                                  ; open EXE file
  1295 00000673 BA[0000]                    mov dx,OFFSET exe_name wrt DGROUP
  1296 00000676 B8023D                      mov ax,3d02h            ; open for read/write access
  1297 00000679 CD21                        int 21h
  1298 0000067B E8(0000)                    call    restore_ems_map
  1299 0000067E 7236                        jc  iled_doserr
  1300                                  
  1301                                  ; read first 10 EXE header bytes
  1302                                  iled_readhdr:
  1303 00000680 A3[0000]                    mov [map_handle],ax       ; save exe handle in map_handle variable
  1304 00000683 89C3                        mov bx,ax
  1305 00000685 B90A00                      mov cx,10
  1306 00000688 BA[3800]                    mov dx,OFFSET exehdr_buff wrt DGROUP
  1307 0000068B B43F                        mov ah,3fh              ; read file
  1308 0000068D CD21                        int 21h
  1309 0000068F E8(0000)                    call    restore_ems_map
  1310 00000692 7222                        jc  iled_doserr         ; error occurred
  1311 00000694 39C8                    	cmp ax, cx
  1312 00000696 B8FEFF                  	mov ax, -2		; short read code
  1313 00000699 751B                    	jne iled_doserr
  1314                                  
  1315                                  ; if not internal overlays, and overlays specified, open OVL file
  1316 0000069B 803E[0000]00                cmp byte [ilf_internal],0      ; see if internal overlays
  1317 000006A0 751A                        jne startseek           ; yes
  1318 000006A2 803E[0000]00                cmp byte [is_anyovls],0        ; see if any overlays
  1319 000006A7 7413                        je  startseek           ; no
  1320                                  
  1321 000006A9 BA[0000]                    mov dx,OFFSET ovl_filename wrt DGROUP
  1322 000006AC B8023D                      mov ax,3d02h            ; open for read/write access
  1323 000006AF CD21                        int 21h
  1324 000006B1 E8(0000)                    call    restore_ems_map
  1325 000006B4 7303                        jnc iled_ovlopen
  1326                                  
  1327                                  iled_doserr:
  1328 000006B6 E9(0000)                    jmp NEAR PTR dos_error
  1329                                  
  1330                                  iled_ovlopen:
  1331 000006B9 A3[0000]                    mov [ovl_handle],ax       ; save overlay handle
  1332                                  
  1333                                  startseek:
  1334 000006BC 803E[0200]00                cmp byte [ilf_inovl],0         ; see if segment is in overlay
  1335 000006C1 7503                        jne iled_inovl          ; yes
  1336 000006C3 E9AA00                      jmp NEAR PTR iled_exeseek   ; no
  1337                                  
  1338                                  iled_inovl:
  1339 000006C6 8B1E[0000]                  mov bx,[ovl_handle]       ; default bx to overlay file handle
  1340 000006CA 803E[0000]00                cmp byte [ilf_internal],0      ; see if internal overlays
  1341 000006CF 7429                        je  iled_3              ; no
  1342                                  
  1343                                  ; internal overlay, move to end of EXE file and then perform as external
  1344 000006D1 8B1E[0000]                  mov bx,[map_handle]       ; get exe file handle
  1345 000006D5 8B0E[3C00]                  mov cx,WORD PTR [exehdr_buff+4]   ; get size of file in 512-byte pages
  1346 000006D9 A1[3A00]                    mov ax,WORD PTR [exehdr_buff+2]   ; get size of file modulo 512
  1347 000006DC 09C0                        or  ax,ax               ; see if any remainder
  1348 000006DE 7401                        je  iled_noremain       ; no
  1349 000006E0 49                          dec cx                  ; drop count of pages
  1350                                  
  1351                                  iled_noremain:
  1352 000006E1 88CE                        mov dh,cl
  1353 000006E3 88E9                        mov cl,ch
  1354 000006E5 30D2                        xor dl,dl
  1355 000006E7 88D5                        mov ch,dl               ; effectively multiply page value by 256 in cx:dx
  1356 000006E9 D1E2                        shl dx,1
  1357 000006EB D1D1                        rcl cx,1                ; get page value*512 in cx:dx
  1358 000006ED 01C2                        add dx,ax               ; add in page remainder
  1359 000006EF 83D100                      adc cx,0                ; carry to high word
  1360 000006F2 B80042                      mov ax,4200h            ; move file pointer, absolute byte offset
  1361 000006F5 CD21                        int 21h
  1362 000006F7 E8(0000)                    call    restore_ems_map
  1363                                  
  1364                                  ; look up file position in ovl file, seek to it, read overlay control bytes.
  1365                                  ; di holds overlay number, stack holds garbage value.
  1366                                  ; change di to zero, stort offset to start of code on stack for use at
  1367                                  ; iled_offseek section of code
  1368                                  iled_3:
  1369 000006FA 4F                          dec di                  ; make overlay number relative zero
  1370 000006FB D1E7                        shl di,1
  1371 000006FD D1E7                        shl di,1
  1372 000006FF 83C702                      add di,2                ; adjust past count of overlays word
  1373                                  
  1374 00000702 89FA                        mov dx,di               ; get low word of file position in ovl file
  1375 00000704 31C9                        xor cx,cx               ; zero high word of file position
  1376                                  
  1377 00000706 B80042                      mov ax,4200h            ; move file pointer, relative beginning of file
  1378 00000709 803E[0000]00                cmp byte [ilf_internal],0      ; see if internal overlays
  1379 0000070E 7402                        je  iled_findfp         ; no
  1380 00000710 FEC0                        inc al                  ; make move relative to current file position
  1381                                  
  1382                                  iled_findfp:
  1383 00000712 CD21                        int 21h
  1384 00000714 E8(0000)                    call    restore_ems_map
  1385                                  
  1386                                  ; read overlay file position
  1387 00000717 B90400                      mov cx,4                ; read doubleword position
  1388 0000071A BA[2A00]                    mov dx,OFFSET ovl_tbuff wrt DGROUP  ; read overlay file position
  1389 0000071D B43F                        mov ah,3fh              ; read file
  1390 0000071F CD21                        int 21h
  1391 00000721 E8(0000)                    call    restore_ems_map
  1392 00000724 7290                        jc  iled_doserr
  1393 00000726 39C8                    	cmp ax, cx
  1394 00000728 B8FEFF                  	mov ax, -2		; short read code
  1395 0000072B 7589                    	jne iled_doserr
  1396                                  
  1397 0000072D 8B16[2A00]                  mov dx,WORD PTR [ovl_tbuff]   ; get low word of position
  1398 00000731 8B0E[2C00]                  mov cx,WORD PTR [ovl_tbuff+2] ; get high word
  1399 00000735 29FA                        sub dx,di               ; adjust for previously positioned to and read in bytes
  1400 00000737 83D900                      sbb cx,0
  1401 0000073A 83EA04                      sub dx,4
  1402 0000073D 83D900                      sbb cx,0
  1403                                  
  1404 00000740 B80142                      mov ax,4201h            ; move file pointer, relative current file position
  1405 00000743 CD21                        int 21h
  1406 00000745 E8(0000)                    call    restore_ems_map
  1407                                  
  1408                                  ; read system information for overlay file (first 5 words)
  1409 00000748 B90A00                      mov cx,10               ; read 10 bytes
  1410 0000074B BA[2A00]                    mov dx,OFFSET ovl_file_header wrt DGROUP    ; read overlay file header bytes
  1411 0000074E B43F                        mov ah,3fh              ; read file
  1412 00000750 CD21                        int 21h
  1413 00000752 E8(0000)                    call    restore_ems_map
  1414 00000755 7303E95CFF              	jc iled_doserr
  1415 0000075A 39C8                    	cmp ax, cx
  1416 0000075C B8FEFF                  	mov ax, -2		; short read code
  1417 0000075F 7403E952FF              	jne iled_doserr
  1418 00000764 58                          pop ax                  ; get garbage value (low word file offset) off stack
  1419 00000765 A1[2C00]                    mov ax,[ofh_ovl_offset]   ; get offset to overlay code
  1420 00000768 83E80A                      sub ax,10               ; adjust for system info bytes read in
  1421 0000076B 50                          push    ax              ; put offset to overlay code on stack for low word file offset
  1422 0000076C 31FF                        xor di,di               ; zero high word offset in di
  1423 0000076E EB22                        jmp SHORT iled_offseek  ; bypass root EXE file setup
  1424                                  
  1425                                  ; in root EXE file, seek past header
  1426                                  iled_exeseek:
  1427 00000770 8B16[4000]                  mov dx,WORD PTR [exehdr_buff+8]   ; get size of header in paragraphs
  1428 00000774 31C9                        xor cx,cx
  1429 00000776 D1E2                        shl dx,1
  1430 00000778 D1D1                        rcl cx,1                ; x2
  1431 0000077A D1E2                        shl dx,1
  1432 0000077C D1D1                        rcl cx,1                ; x4
  1433 0000077E D1E2                        shl dx,1
  1434 00000780 D1D1                        rcl cx,1                ; x8
  1435 00000782 D1E2                        shl dx,1
  1436 00000784 D1D1                        rcl cx,1                ; x16, cx:dx holds byte count of header
  1437 00000786 8B1E[0000]                  mov bx,[map_handle]       ; get exe file handle
  1438 0000078A B80042                      mov ax,4200h            ; move file pointer from start of file
  1439 0000078D CD21                        int 21h
  1440 0000078F E8(0000)                    call    restore_ems_map
  1441                                  
  1442                                  ; at start base in exe or ovl file, bx holds appropriate file handle,
  1443                                  ; seek to code offset
  1444                                  iled_offseek:
  1445 00000792 5A                          pop dx                  ; restore low word of file offset
  1446 00000793 89F9                        mov cx,di               ; get high word of file offset in dx
  1447 00000795 B80142                      mov ax,4201h            ; move file pointer from current location
  1448 00000798 CD21                        int 21h
  1449 0000079A E8(0000)                    call    restore_ems_map
  1450                                  
  1451 0000079D 59                          pop cx                  ; restore count of bytes left in record
  1452 0000079E 26AD                        es lodsw   ; get enumerated data offset
  1453 000007A0 83E902                      sub cx,2                ; drop record byte count
  1454                                  
  1455 000007A3 803E[0200]00                cmp byte [symseg_flag],0       ; see if code or SYMBOLS segment
  1456 000007A8 7402                        je  iled_codeseg        ; code
  1457 000007AA EB5B                        jmp NEAR PTR iled_symseg    ; SYMBOLS segment
  1458                                  
  1459                                  iled_codeseg:
  1460 000007AC 09C0                        or  ax,ax               ; see if zero, if first LEDATA for segment
  1461 000007AE 7528                        jne iled_writedata      ; no, start writing bytes
  1462                                  
  1463                                  ; data offset is zero, first LEDATA, compute offset to adjust past fixup
  1464                                  ; bytes by looking for 9a 00 00 00 00 hex bytes as final fixup and start
  1465                                  ; at first byte following sequence.
  1466 000007B0 31D2                        xor dx,dx               ; dx holds offset
  1467                                  
  1468                                  iled_byteloop:
  1469 000007B2 26AC                        es lodsb   ; get data byte
  1470 000007B4 49                          dec cx
  1471 000007B5 42                          inc dx                  ; bump offset
  1472 000007B6 3C9A                        cmp al,9ah              ; see if start of sequence
  1473 000007B8 75F8                        jne iled_byteloop       ; no
  1474 000007BA 268A04                      mov al,[es:si]
  1475 000007BD 260A4401                    or  al,[es:si+1]
  1476 000007C1 260A4402                    or  al,[es:si+2]
  1477 000007C5 260A4403                    or  al,[es:si+3]        ; al will be zero IFF following four bytes were zero
  1478 000007C9 08C0                        or  al,al
  1479 000007CB 75E5                        jne iled_byteloop       ; sequence not found
  1480                                  
  1481 000007CD 83C604                      add si,4                ; adjust past data bytes sequence
  1482 000007D0 83E904                      sub cx,4
  1483 000007D3 83C204                      add dx,4
  1484 000007D6 89D0                        mov ax,dx               ; offset into ax
  1485                                  
  1486                                  ; es:si -> data bytes, cx-1 is number of bytes to write, ax is offset
  1487                                  ; bx holds proper file handle
  1488                                  iled_writedata:
  1489 000007D8 49                          dec cx                  ; drop number of bytes to write (don't write checksum byte)
  1490 000007D9 89CF                        mov di,cx               ; save number of bytes to write in di
  1491 000007DB 31C9                        xor cx,cx               ; zero high word of file offset
  1492 000007DD 89C2                        mov dx,ax               ; get low word file offset
  1493 000007DF B80142                      mov ax,4201h            ; move file pointer from current location
  1494 000007E2 CD21                        int 21h
  1495 000007E4 E8(0000)                    call    restore_ems_map
  1496 000007E7 89F9                        mov cx,di               ; get bytes to write back in cx
  1497                                  
  1498 000007E9 89F2                        mov dx,si
  1499 000007EB 8CDF                        mov di,ds               ; save -> WarpLink data
  1500 000007ED 06                      	push	es
  1501 000007EE 1F                      	pop	ds					; ds:dx -> object file image containing data bytes
  1502 000007EF B440                        mov ah,40h              ; write to file
  1503 000007F1 CD21                        int 21h
  1504 000007F3 E8(0000)                    call    restore_ems_map
  1505 000007F6 8EDF                        mov ds,di               ; restore ds -> WarpLink data
  1506 000007F8 720A                        jc  iled_todoserr       ; error occurred
  1507 000007FA 39C8                    	cmp ax, cx
  1508 000007FC B82700                  	mov ax, 27h			; insufficient disk space error
  1509 000007FF 7503                    	jne iled_todoserr
  1510 00000801 E99200                      jmp NEAR PTR iled_done  ; successful write
  1511                                  
  1512                                  iled_todoserr:
  1513 00000804 E9(0000)                    jmp NEAR PTR dos_error  ; error occurred
  1514                                  
  1515                                  ; update SYMBOLS segment
  1516                                  ; ax holds data offset, cx holds number of bytes, bx holds file handle
  1517                                  ; es -> object file image
  1518                                  iled_symseg:
  1519 00000807 49                          dec cx                  ; drop number of bytes to read/write (don't write checksum byte)
  1520 00000808 89CF                        mov di,cx               ; save number of bytes to write in di
  1521 0000080A 31C9                        xor cx,cx               ; zero high word of file offset
  1522 0000080C 89C2                        mov dx,ax               ; get low word file offset
  1523 0000080E B80142                      mov ax,4201h            ; move file pointer from current location
  1524 00000811 CD21                        int 21h
  1525 00000813 E8(0000)                    call    restore_ems_map
  1526 00000816 89F9                        mov cx,di               ; get bytes to read/write back in cx
  1527                                  
  1528 00000818 8B16[0A00]                  mov dx,[symbols_buff]     ; get segment of symbols buffer
  1529 0000081C 8EDA                        mov ds,dx
  1530 0000081E 31D2                        xor dx,dx               ; ds:dx -> read buffer
  1531 00000820 B43F                        mov ah,3fh              ; read from file
  1532 00000822 CD21                        int 21h
  1533 00000824 E8(0000)                    call    restore_ems_map
  1534                                  
  1535                                  to_iled_todoserr_CY:
  1536 00000827 72DB                        jc  iled_todoserr       ; error occurred
  1537 00000829 39C8                    	cmp ax, cx
  1538 0000082B B8FEFF                  	mov ax, -2		; short read code
  1539                                  to_iled_todoserr_NZ:
  1540 0000082E 75D4                    	jne iled_todoserr
  1541                                  
  1542                                  ; rewind back to start of segment (-cx bytes)
  1543 00000830 89CF                        mov di,cx               ; save number of bytes to write in di
  1544 00000832 89CA                        mov dx,cx               ; get low word file offset
  1545 00000834 F7DA                        neg dx                  ; make negative
  1546 00000836 B9FFFF                      mov cx,0ffffh           ; negative sign high word of file offset
  1547 00000839 B80142                      mov ax,4201h            ; move file pointer from current location
  1548 0000083C CD21                        int 21h
  1549 0000083E E8(0000)                    call    restore_ems_map
  1550 00000841 89F9                        mov cx,di               ; get bytes to read/write back in cx
  1551                                  
  1552 00000843 31FF                        xor di,di               ; init offset into symbols buffer
  1553 00000845 1E                      	push	ds
  1554 00000846 06                      	push	es
  1555 00000847 1F                      	pop	ds
  1556 00000848 07                      	pop	es
  1557                                  
  1558                                  ; ds:si -> object file buffer
  1559                                  ; es:di -> EXE file symbols buffer
  1560                                  iled_chkfix:
  1561 00000849 268B450C                    mov ax,[es:di+12]
  1562 0000084D 260B450E                    or  ax,[es:di+14]       ; see if nonzero fixup on symbol (can't change name)
  1563 00000851 7415                        je  iled_notproc        ; no fixup, not a procedure reference
  1564                                  
  1565                                  ; procedure, names must match or fail incremental link
  1566 00000853 A7                          cmpsw                   ; see if first two bytes match
  1567 00000854 7548                        jne iled_badproc        ; no, fail
  1568 00000856 A7                          cmpsw                   ; check bytes 3,4
  1569 00000857 7545                        jne iled_badproc
  1570 00000859 A7                          cmpsw                   ; check bytes 5,6
  1571 0000085A 7542                        jne iled_badproc
  1572 0000085C A7                          cmpsw                   ; check bytes 7,8
  1573 0000085D 753F                        jne iled_badproc
  1574 0000085F A7                          cmpsw                   ; check bytes 9,10
  1575 00000860 753C                        jne iled_badproc
  1576 00000862 83EE0A                      sub si,10
  1577 00000865 83EF0A                      sub di,10               ; restore buffer pointer to start of entry
  1578                                  
  1579                                  ; move name from object file buffer to EXE file symbols buffer
  1580                                  iled_notproc:
  1581 00000868 51                          push    cx              ; save count of bytes to write
  1582 00000869 B90600                      mov cx,6                ; 10 chars max/variable name, 5 words + 2 for static flags in 5.0
  1583 0000086C F3A5                        rep movsw               ; move them
  1584 0000086E 59                          pop cx                  ; restore count of bytes to write
  1585 0000086F 83C604                      add si,4
  1586 00000872 83C704                      add di,4                ; bump offset into buffers to next entry
  1587 00000875 39CF                        cmp di,cx               ; see if all entries updated
  1588 00000877 72D0                        jb  iled_chkfix         ; no, move to next entry
  1589 00000879 29CE                        sub si,cx               ; adjust buffer point back to beginning
  1590                                  
  1591 0000087B 1E                      	push	ds
  1592 0000087C 06                      	push	es
  1593 0000087D 1F                      	pop	ds					; ds -> EXE file symbols buffer
  1594 0000087E 07                      	pop	es					; es -> object file
  1595                                  
  1596 0000087F 31D2                        xor dx,dx               ; ds:dx -> write buffer
  1597 00000881 B440                        mov ah,40h              ; write to file
  1598 00000883 CD21                        int 21h
  1599 00000885 E8(0000)                    call    restore_ems_map
  1600 00000888 729D                        jc  to_iled_todoserr_CY    ; error occurred
  1601 0000088A 39C8                    	cmp ax, cx
  1602 0000088C B82700                  	mov ax, 27h			; insufficient disk space error
  1603 0000088F 759D                    	jne to_iled_todoserr_NZ
  1604                                  
  1605 00000891 B8[ssss]                    mov ax,DGROUP
  1606 00000894 8ED8                        mov ds,ax               ; ds -> WarpLink data
  1607                                  
  1608                                  iled_done:
  1609 00000896 01CE                        add si,cx               ; adjust past bytes written
  1610 00000898 B90100                      mov cx,1                ; adjust cx for checksum byte
  1611 0000089B 30C0                        xor al,al               ; indicate to continue with incremental link
  1612 0000089D C3                          ret
  1613                                  
  1614                                  ; a procedure no longer matches its symbol table position
  1615                                  ; restore ds and return al nonzero to fail incremental link
  1616                                  iled_badproc:
  1617 0000089E B8[ssss]                    mov ax,DGROUP
  1618 000008A1 8ED8                        mov ds,ax               ; ds -> WarpLink data
  1619 000008A3 B001                        mov al,1                ; indicate bailout of incremental link
  1620 000008A5 C3                          ret
  1621                                  inc_ledata  ENDP
  1622                                  
  1623                                  ;*****************************
  1624                                  ;* GET_XXX_NAME              *
  1625                                  ;*****************************
  1626                                  
  1627                                  ; get the ILF or QLK name in memory variable ilf_name or qlk_name
  1628                                  ; upon entry di-> proper memory variable, bx -> proper extension, without '.' or null terminator
  1629                                  ; destroys ax,cx,di,si,es
  1630                                  
  1631                                  get_xxx_name    PROC
  1632 000008A6 BE[0000]                    mov si,OFFSET exe_name wrt DGROUP
  1633 000008A9 31C9                        xor cx,cx               ; init count of chars in executable file name
  1634                                  
  1635                                  gin_endloop:
  1636 000008AB AC                          lodsb                   ; char of exe_name file
  1637 000008AC 41                          inc cx                  ; bump count of chars in name
  1638 000008AD 08C0                        or  al,al
  1639 000008AF 75FA                        jne gin_endloop         ; not at end yet, continue
  1640                                  
  1641 000008B1 4E                          dec si                  ; si -> null terminator of name
  1642                                  
  1643                                  gin_startloop:
  1644 000008B2 8A04                        mov al,[si]             ; get char
  1645 000008B4 3C5C                        cmp al,'\'              ; see if directory indicator
  1646 000008B6 7407                        je  gin_gotname         ; yes, at start of name
  1647 000008B8 3C3A                        cmp al,':'              ; see if drive indicator
  1648 000008BA 7403                        je  gin_gotname         ; yes
  1649 000008BC 4E                          dec si                  ; backup to previous char
  1650 000008BD E2F3                        loop    gin_startloop   ; loop thru as many chars as in name
  1651                                  
  1652                                  gin_gotname:
  1653 000008BF 46                          inc si                  ; si -> first char of name
  1654 000008C0 8CD8                        mov ax,ds
  1655 000008C2 8EC0                        mov es,ax               ; es -> WarpLink data
  1656                                  
  1657                                  gin_transloop:
  1658 000008C4 AC                          lodsb                   ; get char of exe name
  1659 000008C5 3C2E                        cmp al,'.'              ; see if extension specifier
  1660 000008C7 7407                        je  add_xxxext          ; yes, add supplied extension instead
  1661 000008C9 08C0                        or  al,al               ; see if at end of name
  1662 000008CB 7403                        je  add_xxxext          ; yes
  1663 000008CD AA                          stosb                   ; transfer char of name
  1664 000008CE EBF4                        jmp SHORT gin_transloop
  1665                                  
  1666                                  ; add extension to exe name, bx -> to it
  1667                                  add_xxxext:
  1668 000008D0 C6052E                      mov BYTE PTR [di],'.'
  1669 000008D3 8A07                    	mov	al,[bx]
  1670 000008D5 884501                      mov BYTE PTR [di+1],al
  1671 000008D8 8A4701                  	mov	al,[bx+1]
  1672 000008DB 884502                      mov BYTE PTR [di+2],al
  1673 000008DE 8A4702                  	mov	al,[bx+2]
  1674 000008E1 884503                      mov BYTE PTR [di+3],al
  1675 000008E4 C6450400                    mov BYTE PTR [di+4],0
  1676 000008E8 C3                          ret
  1677                                  get_xxx_name    ENDP
  1678                                  
  1679                                  ;*****************************
  1680                                  ;* INC_BAILOUT               *
  1681                                  ;*****************************
  1682                                  
  1683                                  ; incremental link has failed, delete exe/ovl/ilf file if modified
  1684                                  ; ask if want to continue with full link
  1685                                  ; destroys ax,bx,cx,dx,di,si
  1686                                  
  1687                                  inc_bailout PROC
  1688 000008E9 833E[0A00]00                cmp word [change_flag],0       ; see if EXE file modified
  1689 000008EE 7435                        je  ib_2                ; no
  1690 000008F0 8B1E[0000]                  mov bx,[map_handle]       ; check if exe handle in map_handle var is nonzero
  1691 000008F4 09DB                        or  bx,bx               ; see if need to delete exe file
  1692 000008F6 7411                        je  ib_chkovl           ; no
  1693 000008F8 B43E                        mov ah,3eh              ; close file before deleting
  1694 000008FA CD21                        int 21h
  1695 000008FC E8(0000)                    call    restore_ems_map
  1696 000008FF BA[0000]                    mov dx,OFFSET exe_name wrt DGROUP
  1697 00000902 B441                        mov ah,41h              ; delete file
  1698 00000904 CD21                        int 21h
  1699 00000906 E8(0000)                    call    restore_ems_map
  1700                                  
  1701                                  ib_chkovl:
  1702 00000909 8B1E[0000]                  mov bx,[ovl_handle]       ; check if ovl handle is nonzero
  1703 0000090D 09DB                        or  bx,bx               ; see if need to delete ovl file
  1704 0000090F 7411                        je  ib_delilf           ; no
  1705 00000911 B43E                        mov ah,3eh              ; close file before deleting
  1706 00000913 CD21                        int 21h
  1707 00000915 E8(0000)                    call    restore_ems_map
  1708 00000918 BA[0000]                    mov dx,OFFSET ovl_filename wrt DGROUP
  1709 0000091B B441                        mov ah,41h              ; delete file
  1710 0000091D CD21                        int 21h
  1711 0000091F E8(0000)                    call    restore_ems_map
  1712                                  
  1713                                  ib_delilf:
  1714 00000922 E87B03                      call    delete_ilf_file
  1715                                  
  1716                                  ib_2:
  1717 00000925 BB[0100]                    mov bx,OFFSET fail_text wrt DGROUP
  1718 00000928 8A4FFF                      mov cl,[bx-1]           ; get length of string to print
  1719 0000092B 89DA                        mov dx,bx               ; ds:dx -> string
  1720 0000092D 30ED                        xor ch,ch               ; zap high byte of cx
  1721 0000092F BB0100                      mov bx,STDOUT           ; write to standard output device
  1722 00000932 B440                        mov ah,40h              ; write to device
  1723 00000934 CD21                        int 21h
  1724 00000936 E8(0000)                    call    restore_ems_map
  1725                                  
  1726 00000939 803E[0000]00                cmp byte [full_linkflag],0     ; see if automatic full link specified
  1727 0000093E 7412                        je  char_loop           ; no
  1728 00000940 BE[4500]                    mov si,OFFSET full_text wrt DGROUP
  1729 00000943 8A4CFF                      mov cl,[si-1]           ; get length of string to print
  1730 00000946 89F2                        mov dx,si               ; ds:dx -> string
  1731 00000948 B440                        mov ah,40h              ; write to device
  1732 0000094A CD21                        int 21h
  1733 0000094C E8(0000)                    call    restore_ems_map
  1734 0000094F E971F7                      jmp NEAR PTR di_new_ilf ; trash old ILF file and create new one
  1735                                  
  1736                                  char_loop:
  1737 00000952 BE[2400]                    mov si,OFFSET proceed_text wrt DGROUP
  1738 00000955 8A4CFF                      mov cl,[si-1]           ; get length of string to print
  1739 00000958 89F2                        mov dx,si               ; ds:dx -> string
  1740 0000095A B440                        mov ah,40h              ; write to device
  1741 0000095C CD21                        int 21h
  1742 0000095E E8(0000)                    call    restore_ems_map
  1743                                  
  1744 00000961 B401                        mov ah,1                ; char input with echo
  1745 00000963 CD21                        int 21h
  1746 00000965 3C79                        cmp al,'y'              ; check if valid char
  1747 00000967 740C                        je  ib_ret
  1748 00000969 3C59                        cmp al,'Y'              ; check if valid char
  1749 0000096B 7408                        je  ib_ret
  1750 0000096D 3C6E                        cmp al,'n'              ; check if valid char
  1751 0000096F 7404                        je  ib_ret
  1752 00000971 3C4E                        cmp al,'N'              ; check if valid char
  1753 00000973 75DD                        jne char_loop           ; nope, loop and try again
  1754                                  
  1755                                  ib_ret:
  1756 00000975 89C6                        mov si,ax               ; save keypress
  1757 00000977 BA[0100]                    mov dx,OFFSET fail_text wrt DGROUP
  1758 0000097A B90200                      mov cx,2                ; print CR/LF duo
  1759 0000097D BB0100                      mov bx,STDOUT           ; write to standard output device
  1760 00000980 B440                        mov ah,40h              ; write to device
  1761 00000982 CD21                        int 21h
  1762 00000984 E8(0000)                    call    restore_ems_map
  1763 00000987 89F0                        mov ax,si               ; get keypress back in al
  1764 00000989 24DF                        and al,0dfh             ; uppercase char
  1765 0000098B 3C59                        cmp al,'Y'              ; see if should perform full link
  1766 0000098D 7503                        jne ib_exit             ; no
  1767 0000098F E931F7                      jmp NEAR PTR di_new_ilf ; yes, trash old ILF file and create new one
  1768                                  
  1769                                  ib_exit:
  1770 00000992 C606[0000]00                mov byte [is_clpinc],0         ; zero clipper incremental link flag
  1771 00000997 C3                          ret
  1772                                  inc_bailout ENDP
  1773                                  
  1774                                  ;*****************************
  1775                                  ;* SETUP_INCINFO             *
  1776                                  ;*****************************
  1777                                  
  1778                                  ; save date/time object number, object name, of object module/library
  1779                                  ; in ilf_entry structure, save pointer to next segpart entry
  1780                                  ; upon entry bx holds file handle
  1781                                  ; destroys ax,cx,dx,di,si,es
  1782                                  
  1783                                  setup_incinfo   PROC
  1784 00000998 C606[0300]00                mov byte [clp_libflag],0       ; init clipper library flag
  1785 0000099D A1[0000]                    mov ax,[alloc_segpartblk_ptr] ; get current segment partition block pointer
  1786 000009A0 A3[1C00]                    mov [ilf_segpart_seg],ax
  1787 000009A3 8EC0                        mov es,ax               ; even if no block allocated yet (es==0), it doesn't matter
  1788 000009A5 26A10000                    mov ax,[es:0]           ; get entry number (invalid if no blocks allocated)
  1789 000009A9 A3[1E00]                    mov [ilf_segpart_ent],ax  ; save it
  1790                                  
  1791 000009AC B80057                      mov ax,5700h            ; get date and time of open file
  1792 000009AF CD21                        int 21h
  1793 000009B1 E8(0000)                    call    restore_ems_map
  1794 000009B4 8916[2800]                  mov [ilf_entry.ie_date],dx
  1795 000009B8 890E[2A00]                  mov [ilf_entry.ie_time],cx
  1796 000009BC 803E[0000]00                cmp byte [is_inlib],0          ; see if processing library
  1797 000009C1 7408                        je  si_procobj          ; no
  1798 000009C3 B91400                      mov cx,14h              ; set library, non-Clipper module bits
  1799 000009C6 A1[0000]                    mov ax,[current_lib]
  1800 000009C9 EB06                        jmp SHORT si_setobjnum
  1801                                  
  1802                                  si_procobj:
  1803 000009CB B91000                      mov cx,10h              ; set non-Clipper module bits
  1804 000009CE A1[0000]                    mov ax,[current_obj]
  1805                                  
  1806                                  si_setobjnum:
  1807 000009D1 A3[2C00]                    mov [ilf_entry.ie_objnum],ax
  1808 000009D4 890E[2600]                  mov [ilf_entry.ie_bitflags],cx    ; set bit flags to defaults
  1809                                  
  1810 000009D8 BE[0000]                    mov si,OFFSET filename wrt DGROUP
  1811                                  
  1812                                  si_null_loop:
  1813 000009DB AC                          lodsb                   ; position to null terminator of filename
  1814 000009DC 08C0                        or  al,al
  1815 000009DE 75FB                        jne si_null_loop        ; not there yet, keep looking
  1816                                  
  1817                                  si_backloop:
  1818 000009E0 8A04                        mov al,[si]
  1819 000009E2 3C5C                        cmp al,'\'              ; back up until hit start or directory/drivespec indicator
  1820 000009E4 740D                        je  si_atname
  1821 000009E6 3C3A                        cmp al,':'
  1822 000009E8 7409                        je  si_atname
  1823 000009EA 81FE[0000]                  cmp si,OFFSET filename wrt DGROUP   ; see if past start
  1824 000009EE 7203                        jb  si_atname
  1825 000009F0 4E                          dec si                  ; back up to previous char
  1826 000009F1 EBED                        jmp SHORT si_backloop
  1827                                  
  1828                                  si_atname:
  1829 000009F3 46                          inc si                  ; si -> first char of name
  1830 000009F4 BF[2E00]                    mov di,OFFSET ilf_entry.ie_objname wrt DGROUP
  1831 000009F7 8CD8                        mov ax,ds
  1832 000009F9 8EC0                        mov es,ax               ; es:di -> place to put nonpathed file name in ilf_entry structure
  1833                                  
  1834                                  si_transloop:
  1835 000009FB A4                          movsb
  1836 000009FC 807CFF00                    cmp BYTE PTR [si-1],0   ; see if null terminator transferred
  1837 00000A00 75F9                        jne si_transloop        ; no
  1838 00000A02 C3                          ret
  1839                                  setup_incinfo   ENDP
  1840                                  
  1841                                  ;*****************************
  1842                                  ;* UPDATE_INCINFO            *
  1843                                  ;*****************************
  1844                                  
  1845                                  ; if not Clipper object module, write object module/library ilf_entry
  1846                                  ; structure to file.
  1847                                  ; if Clipper object module step through each new segpart entry, updating
  1848                                  ; segment length with pad value, setting bitflags, writing ilf_entry
  1849                                  ; destroys ax,bx,dx,di,es
  1850                                  
  1851                                  update_incinfo  PROC
  1852 00000A03 51                          push    cx              ; save critical register
  1853 00000A04 803E[0300]00                cmp byte [clp_libflag],0       ; see if Clipper object module
  1854 00000A09 7555                        jne ui_clip             ; yes
  1855                                  
  1856                                  ; not Clipper object module
  1857 00000A0B A1[0000]                    mov ax,[mod_ovl_count]    ; get count of overlays in this non-Clipper module
  1858 00000A0E 0106[0E00]                  add [ilf_ovl_count],ax    ; update ILF overlay count to adjust for non-Clipper overlays
  1859                                  
  1860                                  ; see if matched previous file entry (lib or obj), if so, don't write anything
  1861                                  ; otherwise write ilf entry and exit
  1862 00000A12 803E[0000]00                cmp byte [is_inlib],0          ; see if in library
  1863 00000A17 750E                        jne ui_inlib            ; yes
  1864 00000A19 A1[0000]                    mov ax,[current_obj]
  1865 00000A1C 3B06[1000]                  cmp ax,[ilf_lastobj]      ; see if previous file entry matches this
  1866 00000A20 A3[1000]                    mov [ilf_lastobj],ax
  1867 00000A23 751C                        jne ui_writenon         ; no
  1868 00000A25 EB37                        jmp SHORT ui_nonret     ; yes
  1869                                  
  1870                                  ui_inlib:
  1871 00000A27 A1[1200]                    mov ax,[ilf_lastlib]      ; get previous file entry
  1872 00000A2A 83F8FF                      cmp ax,-1               ; see if existed
  1873 00000A2D 89C3                        mov bx,ax               ; setup without affecting flags
  1874 00000A2F A1[0000]                    mov ax,[current_lib]      ; get current library in ax
  1875 00000A32 7404                        je  ui_savelib          ; delayed flag, save entry now in ax
  1876 00000A34 39D8                        cmp ax,bx               ; compare current to previous entry number
  1877 00000A36 7626                        jbe ui_nonret           ; library entry equal or below previous, already saved
  1878                                  
  1879                                  ui_savelib:
  1880 00000A38 3B06[2000]                  cmp ax,[start_lib_count]  ; check if a library specified only by default
  1881 00000A3C 7320                        jae ui_nonret           ; yes, don't track it
  1882 00000A3E A3[1200]                    mov [ilf_lastlib],ax      ; save new previous entry
  1883                                  
  1884                                  ui_writenon:
  1885 00000A41 B92000                      mov cx,32               ; write length of entry
  1886 00000A44 BA[2600]                    mov dx,OFFSET ilf_entry wrt DGROUP
  1887 00000A47 8B1E[0800]                  mov bx,[ilf_handle]
  1888 00000A4B B440                        mov ah,40h              ; write to file
  1889 00000A4D CD21                        int 21h
  1890 00000A4F E8(0000)                    call    restore_ems_map
  1891 00000A52 7303                        jnc .checkspace
  1892                                  .error:
  1893 00000A54 E9(0000)                    jmp NEAR PTR dos_error  ; error occurred
  1894                                  
  1895                                  .checkspace:
  1896 00000A57 39C8                    	cmp ax, cx
  1897 00000A59 B82700                  	mov ax, 27h			; insufficient disk space error
  1898 00000A5C 75F6                    	jne .error
  1899                                  
  1900                                  ui_nonret:
  1901 00000A5E 59                          pop cx                  ; restore critical register
  1902 00000A5F C3                          ret
  1903                                  
  1904                                  ui_clip:
  1905 00000A60 31C0                        xor ax,ax
  1906 00000A62 A3[1A00]                    mov [ilf_segdef],ax       ; init ilf segdef index
  1907 00000A65 A1[1C00]                    mov ax,[ilf_segpart_seg]  ; get segment of previously current segment partition block
  1908 00000A68 09C0                        or  ax,ax               ; see if existed
  1909 00000A6A 7509                        jne ui_2                ; yes
  1910                                  
  1911 00000A6C A1[0000]                    mov ax,[first_segpartblk_ptr] ; get segment of first allocated block
  1912 00000A6F 8EC0                        mov es,ax
  1913 00000A71 31C0                        xor ax,ax               ; ax holds new entry-1
  1914 00000A73 EB11                        jmp SHORT ui_firstent
  1915                                  
  1916                                  ui_2:
  1917 00000A75 8EC0                        mov es,ax               ; es-> previously current segment partition block
  1918 00000A77 A1[1E00]                    mov ax,[ilf_segpart_ent]  ; ax holds previously current entry value
  1919 00000A7A 83F840                      cmp ax,SEG_PARTENT_COUNT    ; see if last possible entry
  1920 00000A7D 7207                        jb  ui_firstent         ; no
  1921 00000A7F 268E060200                  mov es,[es:2]           ; es-> next block
  1922 00000A84 31C0                        xor ax,ax               ; ax holds new entry-1
  1923                                  
  1924                                  ; es-> block holding first new entry
  1925                                  ui_firstent:
  1926 00000A86 40                          inc ax                  ; ax holds first new entry value
  1927 00000A87 8CC7                        mov di,es
  1928 00000A89 01C7                        add di,ax               ; di -> first entry in block
  1929                                  
  1930                                  ui_scanloop:
  1931 00000A8B 06                          push    es              ; save -> block
  1932 00000A8C 8EC7                        mov es,di               ; es-> segpart entry
  1933 00000A8E 26800E0F0008                or  BYTE PTR [es:15],8  ; set Clipper object module flag
  1934 00000A94 26A10C00                    mov ax,[es:12]          ; get segment size
  1935 00000A98 09C0                        or  ax,ax               ; see if zero length segment
  1936 00000A9A 7503                        jne ui_notzero          ; no
  1937 00000A9C E9E100                      jmp NEAR PTR ui_nextsegpart ; yes, ignore it
  1938                                  
  1939                                  ui_notzero:
  1940 00000A9F A3[3E00]                    mov [ilf_entry.ie_segsize],ax
  1941 00000AA2 A1[1A00]                    mov ax,[ilf_segdef]       ; save segment index
  1942 00000AA5 A3[3C00]                    mov [ilf_entry.ie_segind],ax
  1943 00000AA8 26A00F00                    mov al,[es:15]          ; get overlay flags
  1944 00000AAC 2480                        and al,80h              ; see if segment is overlaid
  1945 00000AAE 741E                        je  ui_notovl           ; no
  1946                                  
  1947                                  ; overlaid segment, save overlay number, setup bitflags
  1948 00000AB0 A1[0E00]                    mov ax,[ilf_ovl_count]
  1949 00000AB3 A3[4200]                    mov [ilf_entry.ie_ovlnum],ax
  1950 00000AB6 40                          inc ax
  1951 00000AB7 A3[0E00]                    mov [ilf_ovl_count],ax    ; bump count of overlays
  1952                                  
  1953 00000ABA A0[0000]                    mov al,[inc_padval]
  1954 00000ABD 30E4                        xor ah,ah
  1955 00000ABF 2601060C00                  add [es:12],ax          ; adjust segment size in segment partition
  1956 00000AC4 0106[3E00]                  add [ilf_entry.ie_segsize],ax
  1957                                  
  1958 00000AC8 B80900                      mov ax,9                ; show in overlay file and changeable (overlaid always changeable)
  1959 00000ACB E99200                      jmp NEAR PTR ui_writebits
  1960                                  
  1961                                  ; nonoverlaid segment, setup bitflags
  1962                                  ui_notovl:
  1963 00000ACE 8CC1                        mov cx,es               ; save -> segpart entry
  1964 00000AD0 268E060400                  mov es,[es:4]           ; es -> owning segdef entry
  1965                                  
  1966 00000AD5 8CC2                        mov dx,es               ; save -> segdef entry
  1967 00000AD7 26C41E0C00                  les bx,[es:12]          ; es:bx -> class name entry in lnames
  1968 00000ADC 83C308                      add bx,8                ; adjust past prepended doubleword pointers
  1969 00000ADF 31C0                        xor ax,ax               ; set bit flags to default unchangeable
  1970 00000AE1 26803F43                    cmp BYTE PTR [es:bx],'C'
  1971 00000AE5 7531                        jne ui_chksym
  1972 00000AE7 26807F014F                  cmp BYTE PTR [es:bx+1],'O'
  1973 00000AEC 752A                        jne ui_chksym
  1974 00000AEE 26807F0244                  cmp BYTE PTR [es:bx+2],'D'
  1975 00000AF3 7523                        jne ui_chksym
  1976 00000AF5 26807F0345                  cmp BYTE PTR [es:bx+3],'E'
  1977 00000AFA 751C                        jne ui_chksym
  1978                                  
  1979 00000AFC 8EC2                        mov es,dx               ; es -> segdef entry
  1980 00000AFE A0[0000]                    mov al,[inc_padval]
  1981 00000B01 30E4                        xor ah,ah
  1982 00000B03 2601060600                  add [es:6],ax           ; add pad value to segdef segment length
  1983                                  
  1984 00000B08 8EC1                        mov es,cx               ; es -> segpart entry
  1985 00000B0A 2601060C00                  add [es:12],ax          ; adjust segment size in segment partition
  1986 00000B0F 0106[3E00]                  add [ilf_entry.ie_segsize],ax
  1987                                  
  1988 00000B13 B80100                      mov ax,1                ; set bit 0 to indicate changeable
  1989 00000B16 EB48                        jmp SHORT ui_writebits  ; bypass SYMBOLS setup
  1990                                  
  1991                                  ; see if Clipper SYMBOLS class segment
  1992                                  ui_chksym:
  1993 00000B18 26803F53                    cmp BYTE PTR [es:bx],'S'
  1994 00000B1C 7542                        jne ui_writebits
  1995 00000B1E 26807F0159                  cmp BYTE PTR [es:bx+1],'Y'
  1996 00000B23 753B                        jne ui_writebits
  1997 00000B25 26807F024D                  cmp BYTE PTR [es:bx+2],'M'
  1998 00000B2A 7534                        jne ui_writebits
  1999 00000B2C 26807F0342                  cmp BYTE PTR [es:bx+3],'B'
  2000 00000B31 752D                        jne ui_writebits
  2001 00000B33 26807F044F                  cmp BYTE PTR [es:bx+4],'O'
  2002 00000B38 7526                        jne ui_writebits
  2003 00000B3A 26807F054C                  cmp BYTE PTR [es:bx+5],'L'
  2004 00000B3F 751F                        jne ui_writebits
  2005 00000B41 26807F0653                  cmp BYTE PTR [es:bx+6],'S'
  2006 00000B46 7518                        jne ui_writebits
  2007                                  
  2008                                  ; start 04/14/91 change
  2009 00000B48 8EC2                        mov es,dx               ; es -> segdef entry
  2010 00000B4A B82000                      mov ax,32
  2011 00000B4D 2601060600                  add [es:6],ax           ; add 2 symbol entry pad value to segdef segment length
  2012                                  
  2013 00000B52 8EC1                        mov es,cx               ; es -> segpart entry
  2014 00000B54 2601060C00                  add [es:12],ax          ; adjust segment size in segment partition
  2015 00000B59 0106[3E00]                  add [ilf_entry.ie_segsize],ax
  2016                                  ; end 04/14/91 change
  2017                                  
  2018 00000B5D B80200                      mov ax,2                ; set bit 1 to indicate SYMBOLS class segment
  2019                                  
  2020                                  ui_writebits:
  2021 00000B60 A3[2600]                    mov [ilf_entry.ie_bitflags],ax    ; save bit flag state
  2022                                  
  2023                                  ; write ilf_entry
  2024 00000B63 B92000                      mov cx,32               ; write length of entry
  2025 00000B66 BA[2600]                    mov dx,OFFSET ilf_entry wrt DGROUP
  2026 00000B69 8B1E[0800]                  mov bx,[ilf_handle]
  2027 00000B6D B440                        mov ah,40h              ; write to file
  2028 00000B6F CD21                        int 21h
  2029 00000B71 E8(0000)                    call    restore_ems_map
  2030 00000B74 7303                        jnc .checkspace
  2031                                  
  2032                                  .ui_todoserr:
  2033 00000B76 E9(0000)                    jmp NEAR PTR dos_error  ; error occurred
  2034                                  
  2035                                  .checkspace:
  2036 00000B79 39C8                    	cmp ax, cx
  2037 00000B7B B82700                  	mov ax, 27h			; insufficient disk space error
  2038 00000B7E 75F6                    	jne .ui_todoserr
  2039                                  
  2040                                  ui_nextsegpart:
  2041 00000B80 FF06[1A00]                  inc word [ilf_segdef]          ; bump segdef index
  2042 00000B84 47                          inc di                  ; move to next entry
  2043 00000B85 07                          pop es                  ; es-> segpart block
  2044 00000B86 8CC3                        mov bx,es
  2045 00000B88 89F8                        mov ax,di
  2046 00000B8A 29D8                        sub ax,bx               ; ax holds current entry
  2047 00000B8C 263B060000                  cmp ax,[es:0]           ; see if any remaining entries in block
  2048 00000B91 760D                        jbe to_ui_scanloop      ; yes, scan them
  2049 00000B93 26A10200                    mov ax,[es:2]           ; get pointer to next block
  2050 00000B97 09C0                        or  ax,ax               ; see if exists
  2051 00000B99 7408                        je  ui_ret              ; no, done
  2052 00000B9B 8EC0                        mov es,ax               ; es-> new block
  2053 00000B9D 40                          inc ax
  2054 00000B9E 89C7                        mov di,ax               ; di holds first entry
  2055                                  
  2056                                  to_ui_scanloop:
  2057 00000BA0 E9E8FE                      jmp NEAR PTR ui_scanloop
  2058                                  
  2059                                  ui_ret:
  2060 00000BA3 59                          pop cx                  ; restore critical register
  2061 00000BA4 C3                          ret
  2062                                  update_incinfo  ENDP
  2063                                  
  2064                                  ;*****************************
  2065                                  ;* RES_ILFSEG                *
  2066                                  ;*****************************
  2067                                  
  2068                                  ; fill exe/ovl file locations of each segment into ilf file
  2069                                  ; upon entry es-> segdef entry, al == 1 if code segment, ==0 if SYMBOLS
  2070                                  ; ax is destroyed
  2071                                  
  2072                                  res_ilfseg  PROC
  2073 00000BA5 53                          push    bx              ; save critical registers
  2074 00000BA6 51                          push    cx
  2075 00000BA7 52                          push    dx
  2076 00000BA8 3A06[0200]                  cmp al,[symseg_flag]      ; see if switchover to SYMBOLS yet (must rewind file)
  2077 00000BAC 7406                        je  ri_1                ; no
  2078 00000BAE A2[0200]                    mov [symseg_flag],al      ; save new code/SYMBOLS segment flag status
  2079 00000BB1 E89800                      call    ilf_rewind      ; rewind file so start anew, looking for SYMBOLS segments
  2080                                  
  2081                                  ri_1:
  2082 00000BB4 8CC2                        mov dx,es               ; save -> segdef entry
  2083 00000BB6 26A11600                    mov ax,[es:22]          ; get -> first segment partition entry
  2084 00000BBA 09C0                        or  ax,ax               ; see if valid
  2085 00000BBC 740F                        je  to_ri_exit          ; no
  2086 00000BBE 8EC0                        mov es,ax               ; es -> first segment partition entry
  2087 00000BC0 26A00F00                    mov al,[es:15]          ; get flags
  2088 00000BC4 268B0E0C00                  mov cx,[es:12]          ; get segment length in cx
  2089 00000BC9 8EC2                        mov es,dx               ; restore es->segdef entry
  2090 00000BCB 2408                        and al,8                ; check status of Clipper module flag
  2091                                  to_ri_exit:
  2092 00000BCD 7477                        je  ri_exit             ; not a Clipper module
  2093 00000BCF 09C9                        or  cx,cx               ; see if zero segment length
  2094 00000BD1 7473                        je  ri_exit             ; yes, ignore it
  2095                                  
  2096                                  ri_readloop:
  2097 00000BD3 B92000                      mov cx,32               ; read one entry
  2098 00000BD6 BA[2600]                    mov dx,OFFSET ilf_entry wrt DGROUP
  2099 00000BD9 8B1E[0800]                  mov bx,[ilf_handle]
  2100 00000BDD B43F                        mov ah,3fh              ; read file
  2101 00000BDF CD21                        int 21h
  2102 00000BE1 E8(0000)                    call    restore_ems_map
  2103 00000BE4 7303                        jnc ri_2
  2104                                  
  2105                                  ri_todoserr:
  2106 00000BE6 E9(0000)                    jmp NEAR PTR dos_error  ; error occurred
  2107                                  
  2108                                  ri_2:
  2109 00000BE9 39C8                        cmp ax,cx               ; see if eof reached
  2110 00000BEB 755D                        jne ri_internal         ; yes, internal error occurred
  2111 00000BED 89D3                        mov bx,dx
  2112 00000BEF 8B07                        mov ax,[bx]             ; get bit flags
  2113 00000BF1 2403                        and al,3                ; see if changeable/SYMBOLS bits set
  2114 00000BF3 74DE                        je  ri_readloop         ; no, try next entry
  2115                                  
  2116 00000BF5 2401                        and al,1                ; get changeable status
  2117 00000BF7 3A06[0200]                  cmp al,[symseg_flag]      ; see if matches code/SYMBOLS flag
  2118 00000BFB 7402                        je  ri_3                ; yes
  2119                                  
  2120                                  ; either code segment and searching for SYMBOLS, or SYMBOLS segment and
  2121                                  ; searching for code
  2122 00000BFD EBD4                        jmp SHORT ri_readloop   ; move to next entry
  2123                                  
  2124                                  ; at proper entry, save segment offset
  2125                                  ri_3:
  2126 00000BFF 8CC2                        mov dx,es               ; save -> segdef entry
  2127 00000C01 268E061600                  mov es,[es:22]          ; es -> first segment partition entry
  2128 00000C06 26A00F00                    mov al,[es:15]          ; get flags
  2129 00000C0A 8EC2                        mov es,dx               ; restore es->segdef entry
  2130 00000C0C 2480                        and al,80h              ; check overlay status
  2131 00000C0E 750E                        jne ri_write            ; overlaid, no high word of segment length
  2132 00000C10 26A10200                    mov ax,[es:2]
  2133 00000C14 A3[4000]                    mov [ilf_entry.ie_fptrlow],ax ; save low word of segment offset
  2134 00000C17 26A10400                    mov ax,[es:4]           ; get high word of segment offset
  2135 00000C1B A3[4200]                    mov [ilf_entry.ie_ovlnum],ax  ; save it
  2136                                  
  2137                                  ri_write:
  2138 00000C1E 8B1E[0800]                  mov bx,[ilf_handle]
  2139 00000C22 B9FFFF                      mov cx,-1
  2140 00000C25 BAE0FF                      mov dx,-32              ; wind back 32 bytes
  2141 00000C28 B80142                      mov ax,4201h            ; move file pointer from current position
  2142 00000C2B CD21                        int 21h
  2143 00000C2D E8(0000)                    call    restore_ems_map
  2144                                  
  2145 00000C30 B92000                      mov cx,32               ; write one entry, 32 bytes
  2146 00000C33 BA[2600]                    mov dx,OFFSET ilf_entry wrt DGROUP
  2147 00000C36 B440                        mov ah,40h              ; write file
  2148 00000C38 CD21                        int 21h
  2149 00000C3A E8(0000)                    call    restore_ems_map
  2150 00000C3D 72A7                        jc  ri_todoserr
  2151 00000C3F 39C8                    	cmp ax, cx
  2152 00000C41 B82700                  	mov ax, 27h			; insufficient disk space error
  2153 00000C44 75A0                    	jne ri_todoserr
  2154                                  
  2155                                  ri_exit:
  2156 00000C46 5A                          pop dx                  ; restore critical registers
  2157 00000C47 59                          pop cx
  2158 00000C48 5B                          pop bx
  2159 00000C49 C3                          ret
  2160                                  
  2161                                  ; EOF reached prior to resolving all segments
  2162                                  ri_internal:
  2163 00000C4A EBFA                        jmp SHORT ri_exit       ; ignore for now, due to NULLCODE addition
  2164                                  ;***    mov ax,INTERNAL_ERR     ; put WarpLink error code in ax
  2165                                  ;***    mov cx,13               ; internal error value
  2166                                  ;***    jmp NEAR PTR link_error ; transfer control to error handler
  2167                                  
  2168                                  
  2169                                  res_ilfseg  ENDP
  2170                                  
  2171                                  ;*****************************
  2172                                  ;* ILF_REWIND                *
  2173                                  ;*****************************
  2174                                  
  2175                                  ; rewinds ilf file to beginning, just past control info
  2176                                  ; destroys ax,bx,cx,dx
  2177                                  
  2178                                  ilf_rewind  PROC
  2179 00000C4C 803E[0000]00                cmp byte [is_clpinc],0         ; see if Clipper incremental link in process
  2180 00000C51 7411                        je  ir_ret              ; no
  2181 00000C53 8B1E[0800]                  mov bx,[ilf_handle]
  2182 00000C57 31C9                        xor cx,cx
  2183 00000C59 BA2000                      mov dx,32               ; position past control info
  2184 00000C5C B80042                      mov ax,4200h            ; move file pointer from start of file
  2185 00000C5F CD21                        int 21h
  2186 00000C61 E8(0000)                    call    restore_ems_map
  2187                                  
  2188                                  ir_ret:
  2189 00000C64 C3                          ret
  2190                                  ilf_rewind  ENDP
  2191                                  
  2192                                  ;*****************************
  2193                                  ;* ILF_WRITE_EOF             *
  2194                                  ;*****************************
  2195                                  
  2196                                  ; write EOF byte to ILF file and close it
  2197                                  ; destroys ax,bx,cx,dx
  2198                                  
  2199                                  ilf_write_eof   PROC
  2200 00000C65 803E[0000]00                cmp byte [is_clpinc],0         ; see if Clipper incremental link in process
  2201 00000C6A 742F                        je  iwe_ret             ; no
  2202                                  
  2203 00000C6C 31C9                        xor cx,cx
  2204 00000C6E 89CA                        mov dx,cx               ; seek to end of file
  2205 00000C70 8B1E[0800]                  mov bx,[ilf_handle]
  2206 00000C74 B80242                      mov ax,4202h            ; move file pointer relative to end of file
  2207 00000C77 CD21                        int 21h
  2208 00000C79 E8(0000)                    call    restore_ems_map
  2209                                  
  2210 00000C7C B80080                      mov ax,8000h
  2211 00000C7F A3[1A00]                    mov WORD PTR [tbuff],ax
  2212 00000C82 B90200                      mov cx,2                ; write two bytes, eof indicator
  2213 00000C85 BA[1A00]                    mov dx,OFFSET tbuff wrt DGROUP
  2214 00000C88 B440                        mov ah,40h              ; write to file
  2215 00000C8A CD21                        int 21h
  2216 00000C8C E8(0000)                    call    restore_ems_map
  2217                                  
  2218 00000C8F 83F802                      cmp ax,2                ; see if two bytes were written
  2219 00000C92 7508                        jne iwe_delilf          ; no, close and delete ilf file
  2220                                  
  2221 00000C94 B43E                        mov ah,3eh              ; close file
  2222 00000C96 CD21                        int 21h
  2223 00000C98 E8(0000)                    call    restore_ems_map
  2224                                  
  2225                                  iwe_ret:
  2226 00000C9B C3                          ret
  2227                                  
  2228                                  ; close and delete ilf file
  2229                                  iwe_delilf:
  2230 00000C9C E80100                      call    delete_ilf_file
  2231 00000C9F C3                          ret
  2232                                  
  2233                                  ilf_write_eof   ENDP
  2234                                  
  2235                                  ;*****************************
  2236                                  ;* DELETE_ILF_FILE           *
  2237                                  ;*****************************
  2238                                  
  2239                                  ; close and delete the ilf file if it exists
  2240                                  ; destroys ax,bx,cx,dx
  2241                                  
  2242                                  delete_ilf_file PROC
  2243 00000CA0 8B1E[0800]                  mov bx,[ilf_handle]
  2244 00000CA4 09DB                        or  bx,bx               ; see if file exists
  2245 00000CA6 7413                        je  dif_ret             ; no
  2246 00000CA8 B43E                        mov ah,3eh              ; close file
  2247 00000CAA CD21                        int 21h
  2248 00000CAC E8(0000)                    call    restore_ems_map
  2249                                  
  2250 00000CAF BA[4200]                    mov dx,OFFSET ilf_name wrt DGROUP
  2251 00000CB2 B441                        mov ah,41h              ; delete file
  2252 00000CB4 CD21                        int 21h
  2253 00000CB6 31C0                        xor ax,ax               ; zero out file handle so no further deletion attempts
  2254 00000CB8 A3[0800]                    mov [ilf_handle],ax
  2255                                  
  2256                                  dif_ret:
  2257 00000CBB C3                          ret
  2258                                  delete_ilf_file ENDP
  2259                                  
  2260                                  ;*****************************
  2261                                  ;* CHECK_CLIPLIB             *
  2262                                  ;*****************************
  2263                                  
  2264                                  ; upon entry di-> COMENT default library name null terminator
  2265                                  ; destroys ax
  2266                                  
  2267                                  check_cliplib   PROC
  2268 00000CBC 53                          push    bx
  2269 00000CBD 803E[0000]00                cmp byte [is_inlib],0          ; ignore library COMENT fields
  2270 00000CC2 7526                        jne cc_ret
  2271 00000CC4 803E[0000]00                cmp byte [libobj_flag],0       ; ignore library as object module
  2272 00000CC9 751F                        jne cc_ret
  2273                                  ;***    mov ax,di
  2274                                  ;***    sub ax,OFFSET name_field wrt DGROUP ; compute length of library name
  2275                                  ;***    cmp ax,7
  2276                                  ;***    jne cc_ret              ; not proper length for CLIPPER
  2277                                  
  2278                                  ; check for CLIP
  2279 00000CCB BB[0000]                    mov bx,OFFSET name_field wrt DGROUP
  2280 00000CCE 803F43                      cmp BYTE PTR [bx],'C'
  2281 00000CD1 7517                        jne cc_ret              ; not a match
  2282 00000CD3 807F014C                    cmp BYTE PTR [bx+1],'L'
  2283 00000CD7 7511                        jne cc_ret              ; not a match
  2284 00000CD9 807F0249                    cmp BYTE PTR [bx+2],'I'
  2285 00000CDD 750B                        jne cc_ret              ; not a match
  2286 00000CDF 807F0350                    cmp BYTE PTR [bx+3],'P'
  2287 00000CE3 7505                        jne cc_ret              ; not a match
  2288                                  ;***    cmp BYTE PTR [di-3],'P'
  2289                                  ;***    jne cc_ret              ; not a match
  2290                                  ;***    cmp BYTE PTR [di-2],'E'
  2291                                  ;***    jne cc_ret              ; not a match
  2292                                  ;***    cmp BYTE PTR [di-1],'R'
  2293                                  ;***    jne cc_ret              ; not a match
  2294 00000CE5 C606[0300]01                mov byte [clp_libflag],1       ; set clipper library flag (Clipper object module)
  2295                                  
  2296                                  cc_ret:
  2297 00000CEA 5B                          pop bx
  2298 00000CEB C3                          ret
  2299                                  check_cliplib   ENDP
  2300                                  
  2301                                  ;*****************************
  2302                                  ;* DECRYPT                   *
  2303                                  ;*****************************
  2304                                  
  2305                                  ; decrypt encrypted SmartMem library if necessary
  2306                                  ; upon entry ax holds count of bytes to decrypt, buffer_base:dx -> buffer area
  2307                                  ; destroys NO registers
  2308                                  
  2309                                  decrypt PROC
  2310                                  %IFNDEF DEMO
  2311 00000CEC 50                          push    ax              ; save critical register
  2312 00000CED A0[0000]                    mov al,[is_inlib]
  2313 00000CF0 08C0                        or  al,al               ; see if in library
  2314 00000CF2 7410                        je  no_decrypt          ; no
  2315 00000CF4 A0[0000]                    mov al,[is_smartmem]
  2316 00000CF7 08C0                        or  al,al               ; see if smartmem switch set
  2317 00000CF9 7409                        je  no_decrypt          ; no
  2318 00000CFB A1[1600]                    mov ax,[smartmem_count]
  2319 00000CFE 3B06[0000]                  cmp ax,[current_lib]      ; see if current library is smartmem library
  2320 00000D02 7402                        je  do_decrypt          ; yes
  2321                                  
  2322                                  no_decrypt:
  2323 00000D04 58                          pop ax                  ; no, return
  2324 00000D05 C3                          ret
  2325                                  
  2326                                  do_decrypt:
  2327 00000D06 58                          pop ax                  ; get number of bytes to decrypt
  2328 00000D07 50                          push    ax              ; save all used registers
  2329 00000D08 53                          push    bx
  2330 00000D09 51                          push    cx
  2331 00000D0A 1E                          push    ds
  2332                                  
  2333 00000D0B 89C1                        mov cx,ax               ; get number of bytes in cx
  2334 00000D0D 8E1E[0000]                  mov ds,[buffer_base]
  2335 00000D11 89D3                        mov bx,dx               ; ds:dx -> portion to decrypt
  2336                                  
  2337                                  dec_loop:
  2338 00000D13 8A07                        mov al,[bx]             ; get byte to decrypt
  2339 00000D15 342E                        xor al,'.'              ; decrypt it
  2340 00000D17 8807                        mov [bx],al             ; save back decrypted value
  2341 00000D19 43                          inc bx                  ; move to next byte
  2342 00000D1A E2F7                        loop    dec_loop        ; loop until complete
  2343                                  
  2344 00000D1C 1F                          pop ds                  ; restore critical registers
  2345 00000D1D 59                          pop cx
  2346 00000D1E 5B                          pop bx
  2347 00000D1F 58                          pop ax
  2348                                  %ENDIF
  2349 00000D20 C3                          ret
  2350                                  
  2351                                  decrypt ENDP
  2352                                  
  2353                                  ;***** BEGIN WORK
  2354                                  
  2355                                  ;*****************************
  2356                                  ;* CREATE_CLIPMOD_ENTRY      *
  2357                                  ;*****************************
  2358                                  
  2359                                  ; create clipper module entry for symbol table compression use
  2360                                  ; format as follows (12 system bytes):
  2361                                  ;   module ID, 4 bytes
  2362                                  ;   next module pointer, 2 bytes
  2363                                  ;   symbol count, 2 bytes
  2364                                  ;   prior unique symbol count 2 bytes
  2365                                  ;   SYMBOLS segdef index, relative 1, 2 bytes
  2366                                  ;   symbol name counts (offsets with compressed table), 2 bytes per symbol
  2367                                  ;   symbol flags, 1 byte per symbol
  2368                                  ; destroys ax,bx,cx,si,di,es
  2369                                  
  2370                                  create_clipmod_entry	PROC
  2371 00000D21 8E06[0000]              	mov	es,[clipper_segdef_ptr]	; es -> symbols segdef pointer
  2372 00000D25 26A10600                	mov	ax,[es:6]			; get length (symbol count*16)
  2373 00000D29 89C7                    	mov	di,ax
  2374 00000D2B B90300                  	mov	cx,3
  2375 00000D2E D3E8                    	shr	ax,cl				; 2 bytes/symbol
  2376 00000D30 89C3                    	mov	bx,ax
  2377 00000D32 D1EB                    	shr	bx,1				; symbol count
  2378 00000D34 01D8                    	add	ax,bx				; 3 bytes/symbol
  2379 00000D36 50                      	push	ax				; save total symbol byte count
  2380 00000D37 83C01B                  	add	ax,12+15			; clipper module system bytes + round up to next para
  2381 00000D3A 41                      	inc	cx					; cx==4
  2382 00000D3B D3EF                    	shr	di,cl				; di==symbol count
  2383 00000D3D D3E8                    	shr	ax,cl				; ax==total paras need for clipper module entry
  2384                                  
  2385 00000D3F 89C3                    	mov	bx,ax
  2386 00000D41 E8(0000)                	call	alloc_memory	; allocate memory for clipper module entry
  2387 00000D44 833E[0000]00            	cmp	word [first_clipmod_ptr],0	; see if pre-existing clipper module entry
  2388 00000D49 740A                    	je	cce_first			; no
  2389                                  
  2390 00000D4B 8E06[0000]              	mov	es,[current_clipmod_ptr]	; es -> previous clipper module entry
  2391 00000D4F 26A30400                	mov	[es:4],ax			; save -> to next (now current) entry
  2392 00000D53 EB03                    	jmp	SHORT cce_2
  2393                                  
  2394                                  cce_first:
  2395 00000D55 A3[0000]                	mov	[first_clipmod_ptr],ax	; save -> first clipper module entry
  2396                                  
  2397                                  cce_2:
  2398 00000D58 A3[0000]                	mov	[current_clipmod_ptr],ax	; save -> current module
  2399 00000D5B 8EC0                    	mov	es,ax				; es -> current clipper module entry
  2400 00000D5D 26893E0600              	mov	[es:6],di			; save symbol count
  2401 00000D62 A1[0000]                	mov	ax,[clipper_segindex]
  2402 00000D65 26A30A00                	mov	[es:10],ax			; save symbols segment index
  2403 00000D69 31C0                    	xor	ax,ax
  2404 00000D6B 26A30400                	mov	[es:4],ax			; zero next ptr
  2405 00000D6F 26A30200                    mov [es:2],ax			; zero high word of id number
  2406                                  
  2407 00000D73 803E[0000]00                cmp byte [is_inlib],0			; see if processing library module
  2408 00000D78 7410                        je  cce_3				; no
  2409 00000D7A A1[0000]                    mov ax,WORD PTR [lib_id]	; get library id low word
  2410 00000D7D 26A30000                    mov [es:0],ax			; save to file_mod_id number low word
  2411 00000D81 A1[0200]                    mov ax,WORD PTR [lib_id+2]	; get library id high word
  2412 00000D84 26A30200                    mov [es:2],ax			; save to file_mod_id number high word
  2413 00000D88 EB07                        jmp SHORT cce_iddone
  2414                                  
  2415                                  cce_3:
  2416 00000D8A A1[0000]                    mov ax,[current_obj]
  2417 00000D8D 26A30000                    mov [es:0],ax           ; keep id number for pass 2 lookup
  2418                                  
  2419                                  cce_iddone:
  2420 00000D91 59                      	pop	cx					; get symbol entry byte count
  2421 00000D92 BF0C00                  	mov	di,12				; point past 12 system info bytes
  2422 00000D95 31C0                    	xor	ax,ax
  2423 00000D97 D1E9                        shr cx,1                ; convert byte count to zero out to words
  2424 00000D99 F3AB                        rep stosw               ; zero the entries
  2425 00000D9B D1D1                        rcl cx,1                ; pick up carry
  2426 00000D9D F3AA                        rep stosb               ; zero leftover byte, if any
  2427 00000D9F C3                      	ret
  2428                                  create_clipmod_entry	ENDP
  2429                                  
  2430                                  ;*****************************
  2431                                  ;* PARSE_CLIPPER_SYMBOLS     *
  2432                                  ;*****************************
  2433                                  
  2434                                  ; parse through clipper SYMBOLS data if appropriate, compress segment,
  2435                                  ; set up counts in clipper module entry symbol entries
  2436                                  ; upon entry cx=record length,bp=buffer_end, es:si -> enumerated data offset
  2437                                  ; ax==segment index, relative zero
  2438                                  ; destroys bx,dx,di,es
  2439                                  
  2440                                  parse_clipper_symbols	PROC
  2441 00000DA0 803E[0000]A0            	cmp	byte [lxdata],LEDATA		; see if LEDATA record
  2442 00000DA5 7406                    	je	pcs_2
  2443                                  
  2444                                  ; fail
  2445                                  pcs_ret:
  2446 00000DA7 C606[0600]00            	mov	byte [clip_fix_compress],0	; flag no compression on any fixups for this L?DATA
  2447 00000DAC C3                      	ret
  2448                                  
  2449                                  pcs_2:
  2450 00000DAD 803E[0000]00            	cmp	byte [known_clipper],0		; see if known clipper module
  2451 00000DB2 74F3                    	je	pcs_ret				; no
  2452 00000DB4 803E[0000]00            	cmp	byte [symbol_overflow],0	; see if symbol table overflow
  2453 00000DB9 75EC                    	jne	pcs_ret				; yes, don't process table
  2454 00000DBB 3B06[0000]              	cmp	ax,[clipper_segindex]	; see if SYMBOLS segment index
  2455 00000DBF 75E6                    	jne	pcs_ret				; no
  2456                                  
  2457                                  ; LEDATA and SYMBOLS segdef and known_clipper and !symbol_overflow,
  2458 00000DC1 C606[0600]01            	mov	byte [clip_fix_compress],1	; flag compression on fixups for this LEDATA
  2459 00000DC6 50                      	push	ax				; save critical register
  2460 00000DC7 51                      	push	cx
  2461 00000DC8 56                      	push	si
  2462 00000DC9 A1[0000]                	mov	ax,[module_symbol_count]
  2463 00000DCC A3[2800]                	mov	[prev_modsym_count],ax	; save module symbol count up to now
  2464                                  
  2465                                  ; scan past enumerated data offset
  2466 00000DCF 268A04                      mov al,[es:si]          ; get low byte of data offset
  2467 00000DD2 46                          inc si
  2468 00000DD3 49                          dec cx                  ; decrement record length to parse
  2469 00000DD4 39EE                        cmp si,bp               ; check boundary conditions
  2470 00000DD6 7203                        jb  pcs_3               ; okay
  2471 00000DD8 E8(0000)                    call    load_file
  2472                                  pcs_3:
  2473 00000DDB 268A24                      mov ah,[es:si]          ; get high byte of data offset
  2474 00000DDE 46                          inc si
  2475 00000DDF 49                          dec cx                  ; decrement record length to parse
  2476 00000DE0 39EE                        cmp si,bp               ; check boundary conditions
  2477 00000DE2 7203                        jb  pcs_4               ; okay
  2478 00000DE4 E8(0000)                    call    load_file
  2479                                  
  2480                                  ; es:si -> symbol table entries, cx holds total length+1
  2481                                  pcs_4:
  2482 00000DE7 A3[0000]                    mov [rec_offset],ax       ; save data record offset
  2483 00000DEA D1E9                    	shr	cx,1
  2484 00000DEC D1E9                    	shr	cx,1
  2485 00000DEE D1E9                    	shr	cx,1
  2486 00000DF0 D1E9                    	shr	cx,1				; cx holds count of symbol table entries in LEDATA
  2487 00000DF2 8B1E[0000]              	mov	bx,[module_symbol_count]
  2488 00000DF6 01DB                    	add	bx,bx				; convert to word offset
  2489 00000DF8 031E[0000]              	add	bx,[module_symbol_count]	; convert to 3-byte offset
  2490 00000DFC 83C30C                  	add	bx,12				; bx -> current symbol entry
  2491                                  
  2492                                  ; parse through each symbol table entry
  2493                                  pcs_symloop:
  2494 00000DFF 51                      	push	cx				; save count of symbol table entries to parse
  2495 00000E00 06                      	push	es				; save -> i/o buffer
  2496                                  
  2497                                  ; copy symbol table name to symbol name buffer, including bytes after name in 16-byte entry
  2498 00000E01 06                      	push	es
  2499 00000E02 1E                      	push	ds
  2500 00000E03 07                      	pop	es
  2501 00000E04 1F                      	pop	ds					; ds:si -> source
  2502 00000E05 BF[3800]                	mov	di,OFFSET symbol_buffer wrt DGROUP	; es:di -> destination
  2503 00000E08 B91000                  	mov	cx,16				; 16 bytes
  2504                                  
  2505                                  pcs_transloop:
  2506 00000E0B A4                      	movsb
  2507 00000E0C 39EE                        cmp si,bp               ; check boundary conditions
  2508 00000E0E 7203                        jb  pcs_nextchar        ; okay
  2509 00000E10 E8(0000)                    call    load_file
  2510                                  pcs_nextchar:
  2511 00000E13 E2F6                    	loop	pcs_transloop
  2512                                  
  2513 00000E15 56                      	push	si				; save -> next symbol name in LEDATA
  2514 00000E16 06                      	push	es
  2515 00000E17 1F                      	pop	ds					; restore ds -> warplink data
  2516                                  
  2517 00000E18 833E[4200]00            	cmp	WORD PTR [OFFSET symbol_buffer+10 wrt DGROUP],0	; see if static symbol
  2518 00000E1D 7513                    	jne	pcs_nextsym			; yes, leave a zero pointer as indicator
  2519                                  
  2520                                  ; not a static/special symbol
  2521 00000E1F E86100                  	call	find_symbol_entry
  2522 00000E22 8CC0                    	mov	ax,es				; get pointer to symbol table name entry, KEEP FLAGS
  2523 00000E24 8E06[0000]              	mov	es,[current_clipmod_ptr]	; KEEP FLAGS
  2524 00000E28 268907                  	mov	[es:bx],ax			; save pointer for module's symbol count/offset entry, KEEP FLAGS
  2525 00000E2B 7305                    	jnc	pcs_nextsym			; not a new entry
  2526 00000E2D 26804F0210              	or	BYTE PTR [es:bx+2],10h	; flag a new entry created
  2527                                  
  2528                                  pcs_nextsym:
  2529 00000E32 FF06[0000]              	inc	word [module_symbol_count]	; bump current symbol
  2530 00000E36 83C303                  	add	bx,3				; point to next entry
  2531 00000E39 5E                      	pop	si					; get -> last symbol name in LEDATA
  2532 00000E3A 07                      	pop	es
  2533 00000E3B 59                      	pop	cx					; get count of entries to parse
  2534 00000E3C E2C1                    	loop	pcs_symloop		; more symbols
  2535                                  
  2536 00000E3E A1[0000]                	mov	ax,[module_symbol_count]
  2537 00000E41 0306[0000]              	add	ax,[unique_symbol_count]
  2538 00000E45 3D0010                  	cmp	ax,4096				; check if overflow occurred on symbols in program
  2539 00000E48 761E                    	jbe	pcs_chklast
  2540                                  
  2541                                  ; overflow occurred
  2542                                  pcs_overflow:
  2543 00000E4A B8FFFF                  	mov	ax,-1
  2544 00000E4D 8E06[0000]              	mov	es,[current_clipmod_ptr]
  2545 00000E51 26A30200                	mov	[es:2],ax			; -1 high word module ID flags end of clipper symbol table entries
  2546 00000E55 40                      	inc	ax					; ax==0
  2547 00000E56 A2[0600]                	mov	[clip_fix_compress],al	; flag no compression on any fixups for this L?DATA
  2548 00000E59 40                      	inc	ax					; ax==1
  2549 00000E5A A2[0000]                	mov	[symbol_overflow],al	; flag overflow
  2550 00000E5D A1[0000]                	mov	ax,[prev_symbol_count]
  2551 00000E60 A3[0000]                	mov	[unique_symbol_count],ax	; restore unique symbol count to previous
  2552 00000E63 83C406                  	add	sp,6				; get si,es,cx values off of stack
  2553 00000E66 EB17                    	jmp	SHORT pcs_done
  2554                                  
  2555                                  pcs_chklast:
  2556 00000E68 8E06[0000]              	mov	es,[clipper_segdef_ptr]
  2557 00000E6C A1[0000]                	mov	ax,[module_symbol_count]
  2558 00000E6F B104                    	mov	cl,4
  2559 00000E71 D3E0                    	shl	ax,cl				; *16
  2560 00000E73 263B060600              	cmp	ax,[es:6]
  2561 00000E78 7205                    	jb	pcs_done			; not last LEDATA
  2562                                  
  2563 00000E7A C606[0700]01            	mov	byte [must_parse_flag],1	; flag further compression parsing needed for MODEND check
  2564                                  
  2565                                  pcs_done:
  2566 00000E7F 5E                      	pop	si					; restore critical register
  2567 00000E80 59                      	pop	cx
  2568 00000E81 58                      	pop	ax
  2569 00000E82 C3                      	ret
  2570                                  parse_clipper_symbols	ENDP
  2571                                  
  2572                                  ;*****************************
  2573                                  ;* FIND_SYMBOL_ENTRY         *
  2574                                  ;*****************************
  2575                                  
  2576                                  ; search through symbol table entries saved for symbol name in symbol_buffer
  2577                                  ; returns carry flag set if fail (new symbol created), reset on success
  2578                                  ; returns es -> symbol table name entry
  2579                                  ; destroys ax,cx,dx,si,di,es
  2580                                  
  2581                                  find_symbol_entry	PROC
  2582 00000E83 53                      	push	bx				; save critical register
  2583 00000E84 A1[1800]                	mov	ax,[first_syment_ptr]
  2584 00000E87 30D2                    	xor	dl,dl				; dl==0 if no previous, 12 if previous higher, 14 if lower
  2585                                  
  2586                                  fse_comploop:
  2587 00000E89 09C0                    	or	ax,ax				; see if valid segment
  2588 00000E8B 7420                    	je	fse_nomatch			; no
  2589                                  
  2590 00000E8D BE[3800]                	mov	si,OFFSET symbol_buffer wrt DGROUP	; ds:si -> new symbol name
  2591 00000E90 8EC0                    	mov	es,ax
  2592 00000E92 31FF                    	xor	di,di				; es:di -> saved symbol name
  2593                                  
  2594 00000E94 B90500                  	mov	cx,5				; must match to 10 chars
  2595 00000E97 F3A7                    	repe	cmpsw
  2596 00000E99 7445                    	je	fse_match			; match
  2597                                  
  2598                                  ; names didn't match, try next from high/low pointer
  2599                                  fse_trynext:
  2600 00000E9B 7208                    	jc	fse_low
  2601                                  
  2602                                  fse_high:
  2603 00000E9D 26A10C00                	mov	ax,[es:12]			; get high pointer
  2604 00000EA1 B20C                    	mov	dl,12				; flag previous lower
  2605 00000EA3 EBE4                    	jmp	SHORT fse_comploop
  2606                                  
  2607                                  fse_low:
  2608 00000EA5 26A10E00                	mov	ax,[es:14]			; get low pointer
  2609 00000EA9 B20E                    	mov	dl,14				; flag previous higher
  2610 00000EAB EBDC                    	jmp	SHORT fse_comploop
  2611                                  
  2612                                  ; didn't match any symbol names on record, create symbol table entry and update pointers
  2613                                  ; es:di -> final nomatching entry
  2614                                  fse_nomatch:
  2615 00000EAD BB0200                  	mov	bx,2
  2616 00000EB0 E8(0000)                	call	alloc_memory	; allocate 2 paragraphs for symbol table entry
  2617 00000EB3 06                      	push	es				; save -> nonmatching entry needs pointer updated
  2618 00000EB4 8EC0                    	mov	es,ax
  2619 00000EB6 31FF                    	xor	di,di
  2620 00000EB8 BE[3800]                	mov	si,OFFSET symbol_buffer wrt DGROUP	; ds:si -> new symbol name
  2621 00000EBB B90500                  	mov	cx,5				; copy 10 name chars
  2622 00000EBE F3A5                    	rep	movsw
  2623 00000EC0 07                      	pop	es					; es-> nonmatching entry
  2624 00000EC1 08D2                    	or	dl,dl				; see if previous exists
  2625 00000EC3 7416                    	je	fse_first			; no, first ever symbol entry saved
  2626                                  
  2627                                  ; previous pointer exists, dl holds high or low offset
  2628 00000EC5 30F6                    	xor	dh,dh				; zap high byte of offset
  2629 00000EC7 89D7                    	mov	di,dx
  2630 00000EC9 268905                  	mov	[es:di],ax			; update previous pointer
  2631                                  
  2632                                  ; no match found, must create new entry
  2633                                  fse_fail:
  2634 00000ECC 8EC0                    	mov	es,ax				; es -> new entry
  2635 00000ECE 31C0                    	xor	ax,ax
  2636 00000ED0 BF0C00                  	mov	di,12
  2637 00000ED3 AB                      	stosw					; zero out high/low pointers
  2638 00000ED4 AB                      	stosw
  2639 00000ED5 AB                      	stosw					; zero init procedure value, nonproc value, flag byte
  2640 00000ED6 AB                      	stosw
  2641 00000ED7 AA                      	stosb
  2642 00000ED8 F9                      	stc						; show failure (new entry creation)
  2643                                  
  2644                                  fse_out:
  2645 00000ED9 5B                      	pop	bx					; restore critical register
  2646 00000EDA C3                      	ret
  2647                                  
  2648                                  fse_first:
  2649 00000EDB A3[1800]                	mov	[first_syment_ptr],ax	; first, keep pointer to it
  2650 00000EDE EBEC                    	jmp	SHORT fse_fail		; show failure
  2651                                  
  2652                                  ; name matched saved symbol table entry, es -> entry
  2653                                  fse_match:
  2654 00000EE0 F8                      	clc						; show success
  2655 00000EE1 EBF6                    	jmp	SHORT fse_out
  2656                                  
  2657                                  find_symbol_entry	ENDP
  2658                                  
  2659                                  ;*****************************
  2660                                  ;* CLIP_SYM_FIXUP            *
  2661                                  ;*****************************
  2662                                  
  2663                                  ; process fixup on compressed symbol segment LEDATA
  2664                                  ; destroys ax,bx,di
  2665                                  
  2666                                  clip_sym_fixup	PROC
  2667 00000EE3 803E[0600]00            	cmp	byte [clip_fix_compress],0	; see if compressed segment
  2668 00000EE8 7501                    	jne	csf_dofix			; yes
  2669 00000EEA C3                      	ret
  2670                                  
  2671                                  csf_dofix:
  2672 00000EEB 51                      	push	cx				; save critical registers
  2673 00000EEC 56                      	push	si
  2674 00000EED 06                      	push	es
  2675                                  
  2676 00000EEE B103                    	mov	cl,3
  2677 00000EF0 A1[0000]                	mov	ax,[data_rec_offset]	; offset of fixup within this LEDATA
  2678 00000EF3 D3E8                    	shr	ax,cl				; convert to word offset
  2679 00000EF5 24FE                    	and	al,0feh				; mask off leftover bit
  2680 00000EF7 89C3                    	mov	bx,ax
  2681 00000EF9 D1EB                    	shr	bx,1
  2682 00000EFB 01D8                    	add	ax,bx				; 3 bytes offset
  2683                                  
  2684 00000EFD 8B1E[2800]              	mov	bx,[prev_modsym_count]
  2685 00000F01 01DB                    	add	bx,bx				; convert to word offset (offset prior to this LEDATA)
  2686 00000F03 031E[2800]              	add	bx,[prev_modsym_count]	; convert to 3-byte offset
  2687 00000F07 01C3                    	add	bx,ax
  2688 00000F09 83C30C                  	add	bx,12				; adjust past system bytes
  2689 00000F0C 8E06[0000]              	mov	es,[current_clipmod_ptr]	; es:bx -> current entry for fixup
  2690 00000F10 26833F00                	cmp	WORD PTR [es:bx],0	; see if static
  2691 00000F14 741E                    	je	csf_ret				; yes, no new entry needed
  2692                                  
  2693 00000F16 B080                    	mov	al,80h
  2694 00000F18 26084702                	or	BYTE PTR [es:bx+2],al	; flag that this entry was procedure
  2695 00000F1C 8CC1                    	mov	cx,es				; save -> current entry
  2696 00000F1E 268E07                  	mov	es,[es:bx]			; es -> symbol table name entry
  2697                                  
  2698 00000F21 2684061400              	test	BYTE PTR [es:20],al	; see if already flagged as procedure
  2699 00000F26 750C                    	jne	csf_ret				; yes
  2700 00000F28 2608061400              	or	BYTE PTR [es:20],al	; flag as procedure
  2701 00000F2D 8EC1                    	mov	es,cx				; es -> current entry
  2702 00000F2F 26804F0210              	or	BYTE PTR [es:bx+2],10h	; flag as new (not previously flagged as procedure)
  2703                                  
  2704                                  csf_ret:
  2705 00000F34 07                      	pop	es					; restore critical registers
  2706 00000F35 5E                      	pop	si
  2707 00000F36 59                      	pop	cx
  2708 00000F37 C3                      	ret
  2709                                  
  2710                                  clip_sym_fixup	ENDP
  2711                                  
  2712                                  ;*****************************
  2713                                  ;* CLIP_FINAL_COMPRESS       *
  2714                                  ;*****************************
  2715                                  
  2716                                  ; final process of compressed symbols, update pointers to numbers and segment length
  2717                                  ; destroys ax,bx,dx,di
  2718                                  
  2719                                  clip_final_compress	PROC
  2720 00000F38 833E[0000]00            	cmp	word [module_symbol_count],0	; see if any symbols in module
  2721 00000F3D 7501                    	jne	cfc_dofinal			; yes
  2722 00000F3F C3                      	ret
  2723                                  
  2724                                  cfc_dofinal:
  2725 00000F40 51                      	push	cx				; save critical registers
  2726 00000F41 56                      	push	si
  2727 00000F42 06                      	push	es
  2728 00000F43 8B0E[0000]              	mov	cx,[module_symbol_count]
  2729 00000F47 BB0C00                  	mov	bx,12				; adjust past system bytes
  2730                                  
  2731                                  cfc_chkloop:
  2732 00000F4A 8E06[0000]              	mov	es,[current_clipmod_ptr]
  2733 00000F4E 8CC2                    	mov	dx,es				; save -> current clipper module pointer
  2734 00000F50 26833F00                	cmp	WORD PTR [es:bx],0	; see if static
  2735 00000F54 7446                    	je	cfc_static			; yes, automatic new symbol
  2736 00000F56 268A4702                	mov	al,[es:bx+2]		; get flags on current entry
  2737 00000F5A 268E07                  	mov	es,[es:bx]			; es -> symbol table name entry
  2738                                  
  2739                                  ;***** START NEW WORK
  2740                                  
  2741 00000F5D A880                    	test	al,80h			; see if procedure (always flagged in symbol table entry too)
  2742 00000F5F 7406                    	je	cfc_nonproc			; no
  2743 00000F61 A810                    	test	al,10h			; see if new procedure
  2744 00000F63 7530                    	jne	cfc_newproc			; yes
  2745 00000F65 EB21                    	jmp	SHORT cfc_oldproc	; flagged as procedure previously
  2746                                  
  2747                                  ; symbol was a variable
  2748                                  ; symbol is new even if not marked new IFF symbol table entry nonprocedure
  2749                                  ;  flag is not set
  2750                                  cfc_nonproc:
  2751 00000F67 A810                    	test	al,10h			; see if new variable
  2752 00000F69 7508                    	jne	cfc_newvar			; yes
  2753 00000F6B 26F606140040            	test	BYTE PTR [es:20],40h	; see if flagged as variable/nonprocedure
  2754 00000F71 750F                    	jne	cfc_oldvar			; yes
  2755                                  
  2756                                  cfc_newvar:
  2757 00000F73 26800E140040            	or	BYTE PTR [es:20],40h	; flag used as variable, possibly redundant
  2758 00000F79 A1[0000]                	mov	ax,[unique_symbol_count]	; get unique symbol offset
  2759 00000F7C 26A31200                	mov	[es:18],ax				; update variable unique symbol for this entry
  2760 00000F80 EB1D                    	jmp	SHORT cfc_bumpcount
  2761                                  
  2762                                  cfc_oldvar:
  2763 00000F82 26A11200                	mov	ax,[es:18]			; get symbol number of variable
  2764 00000F86 EB04                    	jmp	SHORT cfc_flagcomp	; flag compression of old symbol
  2765                                  
  2766                                  cfc_oldproc:
  2767 00000F88 26A11000                	mov	ax,[es:16]			; get symbol number of procedure
  2768                                  
  2769                                  cfc_flagcomp:
  2770 00000F8C 8EC2                    	mov	es,dx				; es -> current clipper module
  2771 00000F8E 26804F0220              	or	BYTE PTR [es:bx+2],20h	; set compress this symbol flag
  2772 00000F93 EB12                    	jmp	SHORT cfc_change
  2773                                  
  2774                                  ; es -> symbol table name entry
  2775                                  cfc_newproc:
  2776 00000F95 A1[0000]                	mov	ax,[unique_symbol_count]	; get unique symbol offset
  2777 00000F98 26A31000                	mov	[es:16],ax				; update procedure unique symbol for this entry
  2778                                  ; fall through to redundant load, faster than jumping around
  2779                                  
  2780                                  cfc_static:
  2781 00000F9C A1[0000]                	mov	ax,[unique_symbol_count]	; get unique symbol offset
  2782                                  
  2783                                  cfc_bumpcount:
  2784 00000F9F FF06[0000]              	inc	word [unique_symbol_count]	; bump count of uniques
  2785 00000FA3 8E06[0000]              	mov	es,[current_clipmod_ptr]
  2786                                  
  2787                                  cfc_change:
  2788 00000FA7 268907                  	mov	[es:bx],ax			; change pointer to offset
  2789                                  
  2790                                  ;***** STOP NEW WORK
  2791                                  
  2792                                  ; move to next entry, if any
  2793                                  cfc_next:
  2794 00000FAA 83C303                  	add	bx,3
  2795 00000FAD E29B                    	loop	cfc_chkloop		; loop thru all entries
  2796                                  
  2797                                  ; update segment length, clipper module unique symbol count
  2798 00000FAF 8B16[0000]              	mov	dx,[prev_symbol_count]
  2799 00000FB3 A1[0000]                	mov	ax,[unique_symbol_count]
  2800 00000FB6 29D0                    	sub	ax,dx				; compute nonduplicate symbol count for module
  2801 00000FB8 B104                    	mov	cl,4
  2802 00000FBA D3E0                    	shl	ax,cl
  2803 00000FBC 8E06[0000]              	mov	es,[clipper_segdef_ptr]
  2804 00000FC0 26A30600                	mov	[es:6],ax			; update segment length
  2805 00000FC4 8E06[0000]              	mov	es,[current_clipmod_ptr]
  2806 00000FC8 2689160800              	mov	[es:8],dx			; save unique symbols previous to this module
  2807                                  
  2808                                  cfc_ret:
  2809 00000FCD 07                      	pop	es					; restore critical registers
  2810 00000FCE 5E                      	pop	si
  2811 00000FCF 59                      	pop	cx
  2812 00000FD0 C3                      	ret
  2813                                  
  2814                                  clip_final_compress	ENDP
  2815                                  
  2816                                  ;*****************************
  2817                                  ;* PASS2_CLIPCHECK           *
  2818                                  ;*****************************
  2819                                  
  2820                                  ; see if Clipper module that is compressed, set appropriate flags if so
  2821                                  ; destroys ax,bx,cx,dx,di,es
  2822                                  
  2823                                  pass2_clipcheck	PROC
  2824 00000FD1 31C0                    	xor	ax,ax
  2825 00000FD3 89C7                    	mov	di,ax				; di is constant zero in this routine
  2826 00000FD5 A2[0400]                	mov	[compress_this],al	; init compress this module flag
  2827 00000FD8 3806[0000]              	cmp	[compression_flag],al	; see if Clipper symbol table compression in force
  2828 00000FDC 744B                    	je	pop_ret				; no
  2829                                  
  2830 00000FDE 3806[0000]                  cmp [is_inlib],al			; see if processing library module
  2831 00000FE2 7546                        jne	pop_islib			; yes
  2832                                  	
  2833 00000FE4 3906[0000]              	cmp	[current_clipmod_ptr],ax	; see if any clipper modules previous
  2834 00000FE8 741C                    	je	pop_clipfirst		; no
  2835                                  
  2836 00000FEA 8E06[0000]              	mov	es,[current_clipmod_ptr]
  2837 00000FEE 26A10400                	mov	ax,[es:4]			; get next module pointer
  2838 00000FF2 09C0                    	or	ax,ax				; see if next module exists
  2839 00000FF4 740A                    	je	pop_endcomp			; no
  2840 00000FF6 8EC0                    	mov	es,ax				; es -> next clipper module
  2841 00000FF8 26833E0200FF            	cmp	WORD PTR [es:2],-1	; see if next module overflowed
  2842 00000FFE 750A                    	jne	pop_clipchk			; no, check if this module has clipper entry
  2843                                  
  2844                                  pop_endcomp:
  2845 00001000 31C0                    	xor	ax,ax
  2846                                  ;***    cmp is_inlib,al			; see if processing library module
  2847                                  ;***    jne	pop_ret				; yes, don't auto-shut off compression
  2848 00001002 A2[0000]                	mov	[compression_flag],al	; shut off further symbol compression
  2849 00001005 C3                      	ret
  2850                                  
  2851                                  pop_clipfirst:
  2852 00001006 8E06[0000]              	mov	es,[first_clipmod_ptr]
  2853                                  
  2854                                  ; compare module id in [es:0] against current module id
  2855                                  ; if match set compress_this variable, update current_clipmod_ptr variable
  2856                                  pop_clipchk:
  2857 0000100A A1[0000]                	mov	ax,[current_obj]
  2858 0000100D 263905                  	cmp	[es:di],ax			; see if module id matches
  2859 00001010 7517                    	jne	pop_ret				; no
  2860 00001012 26393E0200              	cmp	[es:2],di
  2861 00001017 7510                    	jne	pop_ret				; no match
  2862                                  
  2863                                  ; successful match
  2864                                  pop_match:
  2865 00001019 C606[0400]01            	mov	byte [compress_this],1		; flag compression on this module
  2866 0000101E 8C06[0000]              	mov	[current_clipmod_ptr],es	; update current clipper module pointer
  2867 00001022 26A10A00                	mov	ax,[es:10]			; get SYMBOLS segment index, relative 0
  2868 00001026 A3[0000]                	mov	[clipper_segindex],ax	; save symbols segment index for LEDATA lookup
  2869                                  
  2870                                  pop_ret:
  2871 00001029 C3                      	ret
  2872                                  
  2873                                  ; the library module entries can be mixed up so have to check all entries
  2874                                  ; for ID from the beginning
  2875                                  pop_islib:
  2876 0000102A 8E06[0000]              	mov	es,[first_clipmod_ptr]
  2877 0000102E 8B1E[0000]              	mov	bx,WORD PTR [lib_id]
  2878 00001032 8B16[0200]              	mov	dx,WORD PTR [lib_id+2]
  2879                                  
  2880                                  pop_libid:
  2881 00001036 26391D                  	cmp	[es:di],bx			; see if library id matches
  2882 00001039 7507                    	jne	pop_endchk			; no
  2883 0000103B 2639160200              	cmp	[es:2],dx			; check high word id
  2884 00001040 74D7                    	je	pop_match			; succesful
  2885                                  
  2886                                  ; check if at end of module entries for library ID scan
  2887                                  pop_endchk:
  2888 00001042 26A10400                	mov	ax,[es:4]			; get next module pointer
  2889 00001046 09C0                    	or	ax,ax				; see if next module exists
  2890 00001048 74DF                    	je	pop_ret				; no
  2891 0000104A 8EC0                    	mov	es,ax				; es -> next clipper module
  2892 0000104C 26833E0200FF            	cmp	WORD PTR [es:2],-1	; see if next module overflowed
  2893 00001052 75E2                    	jne	pop_libid			; no, check its ID
  2894 00001054 C3                      	ret						; done, no match in all entries
  2895                                  
  2896                                  pass2_clipcheck	ENDP
  2897                                  
  2898                                  ;*****************************
  2899                                  ;* FIXUP_CLIPPER_TOKENS      *
  2900                                  ;*****************************
  2901                                  
  2902                                  ; fixup tokens in Clipper code
  2903                                  ; upon entry cx == count of data bytes, [es:si] -> first data byte
  2904                                  ; destroys ax,bx,dx,di
  2905                                  
  2906                                  fixup_clipper_tokens	PROC
  2907 00001055 51                      	push	cx				; save critical register
  2908 00001056 56                      	push	si
  2909 00001057 803E[0000]00            	cmp	byte [is_clipper5],0		; see if clipper 5 code
  2910 0000105C 742A                    	je	fct_summer87		; no, summer 87 code
  2911                                  
  2912                                  ; clipper 5 code
  2913 0000105E BB[A401]                	mov	bx,OFFSET clipper5_table wrt DGROUP
  2914 00001061 B201                    	mov	dl,1				; Clipper 5 ASCIIZ opcode
  2915 00001063 B660                    	mov	dh,60h				; Clipper 5 end of code token
  2916 00001065 BF[9300]                	mov	di,OFFSET clipper5_token_list wrt DGROUP	; di -> list of tokens that require fixup
  2917 00001068 30C0                    	xor	al,al
  2918 0000106A 3806[0500]              	cmp	[old_parse_proc],al	; see if parsing new procedure
  2919 0000106E 7542                    	jne	fct_scanloop		; no
  2920 00001070 FEC0                    	inc	al
  2921 00001072 A2[0500]                	mov	[old_parse_proc],al	; set flag to bypass header next time
  2922 00001075 83C616                  	add	si,16h				; adjust for header at start of p-code
  2923 00001078 3B36[0000]              	cmp	si,[buffer_end]		; see if past buffer end
  2924 0000107C 7204                    	jb	fct_c52				; no
  2925 0000107E 2B36[0000]              	sub	si,[buffer_end]		; wrap buffer
  2926                                  
  2927                                  fct_c52:
  2928 00001082 83E916                  	sub	cx,16h
  2929 00001085 E9DC00                  	jmp	NEAR PTR  fct_endchk
  2930                                  
  2931                                  ; summer 87 code
  2932                                  fct_summer87:
  2933 00001088 BB[A400]                	mov	bx,OFFSET summer87_table wrt DGROUP
  2934 0000108B B297                    	mov	dl,97h				; Summer 87 ASCIIZ opcode
  2935 0000108D B634                    	mov	dh,34h				; Summer 87 end of code token
  2936 0000108F BF[8200]                	mov	di,OFFSET summer87_token_list wrt DGROUP	; di -> list of tokens that require fixup
  2937 00001092 30C0                    	xor	al,al
  2938 00001094 3806[0500]              	cmp	[old_parse_proc],al	; see if parsing new procedure
  2939 00001098 7518                    	jne	fct_scanloop		; no
  2940 0000109A FEC0                    	inc	al
  2941 0000109C A2[0500]                	mov	[old_parse_proc],al	; set flag to bypass header next time
  2942 0000109F 83C61D                  	add	si,1dh				; adjust for header at start of p-code
  2943 000010A2 3B36[0000]              	cmp	si,[buffer_end]		; see if past buffer end
  2944 000010A6 7204                    	jb	fct_sum2			; no
  2945 000010A8 2B36[0000]              	sub	si,[buffer_end]		; wrap buffer
  2946                                  
  2947                                  fct_sum2:
  2948 000010AC 83E91D                  	sub	cx,1dh
  2949 000010AF E9B200                  	jmp	NEAR PTR  fct_endchk
  2950                                  
  2951                                  ; main p-code scanning loop
  2952                                  fct_scanloop:
  2953 000010B2 268A04                  	mov	al,[es:si]			; get data byte
  2954                                  
  2955                                  ; left_to_parse can hold the following values
  2956                                  ; 	0==parsing a new token value
  2957                                  ;	<10h==parsing an old token value, number of bytes left to parse
  2958                                  ;	10h==parsing a length byte
  2959                                  ;	21h==parsing symbol offset high byte
  2960                                  ;	22h==parsing symbol offset low byte
  2961                                  
  2962 000010B5 803E[0300]00            	cmp	byte [left_to_parse],0		; see if parsing new token
  2963 000010BA 754A                    	jne	fct_notnew			; no
  2964                                  
  2965                                  ; parsing new token value
  2966 000010BC 38F0                    	cmp	al,dh				; see if end of code token
  2967 000010BE 7412                    	je	fct_ended			; yes
  2968 000010C0 88C4                    	mov	ah,al				; save token value
  2969 000010C2 D7                      	xlat					; look up length byte
  2970 000010C3 08C0                    	or	al,al				; zero if illegal token
  2971 000010C5 7519                    	jne	fct_validtoken		; valid token
  2972                                  
  2973                                  ; illegal token encountered
  2974 000010C7 BA[0000]                    mov dx,OFFSET filename wrt DGROUP
  2975 000010CA 88E1                    	mov	cl,ah				; bad value in cl
  2976 000010CC B84A00                      mov ax,SYMBOLTOKEN_ERR	; bad Clipper symbol token
  2977 000010CF E9(0000)                    jmp NEAR PTR link_error	; transfer control to error handler
  2978                                  
  2979                                  fct_ended:
  2980 000010D2 30C0                    	xor	al,al
  2981 000010D4 A2[0300]                	mov	[left_to_parse],al	; reset parsing flag for next module
  2982 000010D7 A2[0400]                	mov	[parse_length],al		; zero parse length byte
  2983 000010DA A2[0500]                	mov	[old_parse_proc],al	; reset parsing old procedure flag
  2984 000010DD E9C300                  	jmp	NEAR PTR fct_done
  2985                                  
  2986                                  fct_validtoken:
  2987 000010E0 38D4                    	cmp	ah,dl				; see if ASCIIZ string opcode (ignore length lookup)
  2988 000010E2 7507                    	jne	fct_notasciiz		; no
  2989 000010E4 C606[0300]11            	mov	byte [left_to_parse],11h	; flag parsing a length byte next, adjust 1 for autodecrement
  2990 000010E9 EB4F                    	jmp	SHORT fct_nextbyte
  2991                                  
  2992                                  fct_notasciiz:
  2993 000010EB A2[0300]                	mov	[left_to_parse],al	; save length of token to parse
  2994                                  
  2995                                  ; check if token has symbol that requires fixing up
  2996 000010EE 51                      	push	cx
  2997 000010EF 57                      	push	di
  2998 000010F0 B91100                  	mov	cx,17				; seventeen possibilities (for Clipper 5, padded from 6 in S'87)
  2999                                  
  3000                                  fct_comploop:
  3001 000010F3 3A25                    	cmp	ah,[di]			; see if a match
  3002 000010F5 7508                    	jne	fct_chknextsym		; no
  3003 000010F7 C606[0300]23            	mov	byte [left_to_parse],23h	; flag parsing a symbol offset next, adjust 1 for autodecrement
  3004 000010FC B90100                  	mov	cx,1				; force loop to end
  3005                                  
  3006                                  fct_chknextsym:
  3007 000010FF 47                      	inc	di					; try next
  3008 00001100 E2F1                    	loop	fct_comploop
  3009 00001102 5F                      	pop	di
  3010 00001103 59                      	pop	cx
  3011 00001104 EB34                    	jmp	SHORT fct_nextbyte
  3012                                  
  3013                                  ; check if parsing asciiz string content (parse_length!=0, parse_length && left_to_parse==content length)
  3014                                  ; if so, decrement parse_length
  3015                                  fct_notnew:
  3016 00001106 803E[0400]00            	cmp	byte [parse_length],0
  3017 0000110B 7406                    	je	fct_chklen
  3018 0000110D FE0E[0400]              	dec	byte [parse_length]
  3019 00001111 EB27                    	jmp	SHORT fct_nextbyte
  3020                                  
  3021                                  ; check if parsing asciiz string length byte (parse_length==0, left_to_parse==10h)
  3022                                  ; if so, set parse_length, left_to_parse bytes
  3023                                  fct_chklen:
  3024 00001113 803E[0300]10            	cmp	byte [left_to_parse],10h
  3025 00001118 750A                    	jne	fct_chkofflow
  3026 0000111A 40                      	inc	ax					; adjust for null terminator
  3027 0000111B A2[0400]                	mov	[parse_length],al
  3028 0000111E 40                      	inc	ax					; adjust for length byte
  3029 0000111F A2[0300]                	mov	[left_to_parse],al
  3030 00001122 EB16                    	jmp	SHORT fct_nextbyte
  3031                                  
  3032                                  ; check if parsing symbol offset low byte (parse_length==0, left_to_parse==22h)
  3033                                  ; if so, save value
  3034                                  fct_chkofflow:
  3035 00001124 803E[0300]22            	cmp	byte [left_to_parse],22h
  3036 00001129 7505                    	jne	fct_chkoffhigh
  3037 0000112B A2[2200]                	mov	BYTE PTR [parse_symoff],al
  3038 0000112E EB0A                    	jmp	SHORT fct_nextbyte
  3039                                  
  3040                                  ; check if parsing symbol offset high byte (parse_length==0, left_to_parse==21h)
  3041                                  ; if so, save value, else scanning past token arguments, ignore
  3042                                  fct_chkoffhigh:
  3043 00001130 803E[0300]21            	cmp	byte [left_to_parse],21h
  3044 00001135 7503                    	jne	fct_nextbyte
  3045 00001137 A2[2300]                	mov	BYTE PTR [parse_symoff+1],al
  3046                                  
  3047                                  ; get next byte in token scanning
  3048                                  fct_nextbyte:
  3049 0000113A 46                      	inc	si					; bump -> into data record
  3050 0000113B 3B36[0000]              	cmp	si,[buffer_end]		; see if past buffer end
  3051 0000113F 7202                    	jb	fct_next2			; no
  3052 00001141 31F6                    	xor	si,si				; yes, wrap buffer
  3053                                  
  3054                                  fct_next2:
  3055 00001143 49                      	dec	cx					; drop count of bytes in data record
  3056 00001144 FE0E[0300]              	dec	byte [left_to_parse]		; drop count of bytes left to parse
  3057 00001148 803E[0400]00            	cmp	byte [parse_length],0		; see if parsing asciiz
  3058 0000114D 7515                    	jne	fct_endchk			; yes
  3059 0000114F A0[0300]                	mov	al,[left_to_parse]
  3060 00001152 A81F                    	test	al,1fh			; get value with symbol offset flag masked
  3061 00001154 750E                    	jne	fct_endchk			; more bytes associated with token, see if at end of data record
  3062                                  
  3063                                  ; end of bytes associate with token
  3064 00001156 C606[0400]00            	mov	byte [parse_length],0		; zero parse length byte
  3065 0000115B C606[0300]00            	mov	byte [left_to_parse],0		; zero out left_to_parse
  3066 00001160 2420                    	and	al,20h				; see if scanned out symbol offset
  3067 00001162 7505                    	jne	fct_symfix			; yes
  3068                                  
  3069                                  fct_endchk:
  3070 00001164 E33D                    	jcxz	fct_done		; no more bytes in data record
  3071 00001166 E949FF                  	jmp	NEAR PTR fct_scanloop
  3072                                  
  3073                                  ; need to fix up this symbol
  3074                                  fct_symfix:
  3075 00001169 57                      	push	di				; save critical register
  3076 0000116A 06                      	push	es
  3077 0000116B 8E06[0000]              	mov	es,[current_clipmod_ptr]
  3078 0000116F 8B3E[2200]              	mov	di,[parse_symoff]		; get symbol offst
  3079 00001173 01FF                    	add	di,di				; make word offset
  3080 00001175 033E[2200]              	add	di,[parse_symoff]		; make 3-byte offset
  3081 00001179 83C70C                  	add	di,12				; adjust past system bytes
  3082                                  
  3083                                  ; [es:di]-> symbol table count for this symbol
  3084 0000117C 268B05                  	mov	ax,[es:di]			; get new symbol number
  3085                                  
  3086                                  fct_symupd:
  3087 0000117F 07                      	pop	es
  3088 00001180 06                      	push	es				; es -> i/o buffer and back on stack
  3089 00001181 83FE02                  	cmp	si,2				; see if buffer wrap
  3090 00001184 7315                    	jae	fct_nowrap			; no
  3091 00001186 8B3E[0000]              	mov	di,[buffer_end]		; point to end of buffer for wrap compensation
  3092 0000118A 4F                      	dec	di					; di-> last valid byte
  3093 0000118B 83FE01                  	cmp	si,1				; see if buffer straddle
  3094 0000118E 7404                    	je	fct_straddle		; yes
  3095                                  
  3096                                  ; update at old buffer end
  3097 00001190 4F                      	dec	di					; di -> second to last valid byte
  3098 00001191 AB                      	stosw
  3099 00001192 EB0B                    	jmp	SHORT fct_upddone
  3100                                  
  3101                                  ; straddle buffer
  3102                                  fct_straddle:
  3103 00001194 AA                      	stosb
  3104 00001195 268864FF                	mov	[es:si-1],ah
  3105 00001199 EB04                    	jmp	SHORT fct_upddone
  3106                                  
  3107                                  fct_nowrap:
  3108 0000119B 268944FE                	mov	[es:si-2],ax		; overwrite old symbol number
  3109                                  
  3110                                  fct_upddone:
  3111 0000119F 07                      	pop	es					; restore critical register
  3112 000011A0 5F                      	pop	di
  3113 000011A1 EBC1                    	jmp	SHORT fct_endchk
  3114                                  
  3115                                  fct_done:
  3116 000011A3 5E                      	pop	si					; restore critical register
  3117 000011A4 59                      	pop	cx
  3118 000011A5 C3                      	ret
  3119                                  fixup_clipper_tokens	ENDP
  3120                                  
  3121                                  ;*****************************
  3122                                  ;* PROCESS_SYMBOL_TABLE      *
  3123                                  ;*****************************
  3124                                  
  3125                                  ; process the symbol table data
  3126                                  ; upon entry cx == count of data bytes, [es:si] -> first data byte
  3127                                  ; rec_offset holds LEDATA data offset
  3128                                  ; modifies cx to == new count of data bytes after compression
  3129                                  ; destroys ax,bx,dx,di
  3130                                  
  3131                                  process_symbol_table	PROC
  3132 000011A6 56                      	push	si				; save critical register
  3133 000011A7 06                      	push	es
  3134                                  
  3135 000011A8 C706[2600]0000          	mov	word [reloc_lowwater],0	; init relocation low water mark
  3136 000011AE 8B1E[0000]              	mov	bx,[rec_offset]
  3137 000011B2 D1EB                    	shr	bx,1
  3138 000011B4 D1EB                    	shr	bx,1
  3139 000011B6 D1EB                    	shr	bx,1				; bx holds symbol number within module (word offset)
  3140 000011B8 89DA                    	mov	dx,bx
  3141 000011BA D1EA                    	shr	dx,1
  3142 000011BC 01D3                    	add	bx,dx				; make 3-byte offset
  3143 000011BE 83C30C                  	add	bx,12				; adjust past system bytes
  3144 000011C1 89CA                    	mov	dx,cx				; dx holds count of bytes after compression removal
  3145                                  
  3146                                  pct_comploop:
  3147 000011C3 8E06[0000]              	mov	es,[current_clipmod_ptr]	; [es:bx] -> symbol table entry
  3148 000011C7 26F6470220              	test	BYTE PTR [es:bx+2],20h	; see if compressed symbol
  3149 000011CC 7503                    	jne	pct_comp			; yes
  3150 000011CE E98300                  	jmp	NEAR PTR pct_nocomp	; no
  3151                                  
  3152                                  ; this symbol was compressed, remove its entry from LEDATA data
  3153                                  pct_comp:
  3154 000011D1 07                      	pop	es					; es -> destination (i/o buffer)
  3155 000011D2 06                      	push	es				; save back on stack
  3156 000011D3 56                      	push	si				; save critical registers
  3157 000011D4 51                      	push	cx
  3158                                  
  3159 000011D5 1E                      	push	ds
  3160 000011D6 89F7                    	mov	di,si				; di -> destination (overwrite this symbol in LEDATA)
  3161 000011D8 83C610                  	add	si,16				; si -> source
  3162 000011DB 7206                    	jc	pcs_of2				; overflow
  3163 000011DD 3B36[0000]              	cmp	si,[buffer_end]		; see if past buffer
  3164 000011E1 7211                    	jb	pct_transfer		; no
  3165                                  
  3166                                  ; buffer wrap/overflow
  3167                                  pcs_of2:
  3168 000011E3 2B36[0000]              	sub	si,[buffer_end]
  3169 000011E7 EB0B                    	jmp	SHORT pct_transfer
  3170                                  
  3171                                  ; stepping stone to pct_done
  3172                                  to_pct_done:
  3173 000011E9 E98700                  	jmp	NEAR PTR pct_done
  3174                                  
  3175                                  pct_dioverf:
  3176 000011EC 31FF                    	xor	di,di				; wrap di
  3177 000011EE EB31                    	jmp	SHORT pct_trans1
  3178                                  
  3179                                  pct_sioverf:
  3180 000011F0 31F6                    	xor	si,si				; wrap si
  3181 000011F2 EB31                    	jmp	SHORT pct_trans2
  3182                                  
  3183                                  pct_transfer:
  3184 000011F4 83E910                  	sub	cx,16				; move all remaining bytes between symbol entry and end
  3185 000011F7 742F                    	je	pct_transdone		; no bytes to transfer
  3186 000011F9 06                      	push	es
  3187                                  
  3188 000011FA 89C8                    	mov	ax,cx				; check for buffer overflow (slow transfer code)
  3189 000011FC 01F8                    	add	ax,di
  3190 000011FE 7219                    	jc	pct_buffover		; buffer overflow will occur
  3191 00001200 3B06[0000]              	cmp	ax,[buffer_end]
  3192 00001204 7313                    	jae	pct_buffover		; buffer overflow will occur
  3193 00001206 89C8                    	mov	ax,cx
  3194 00001208 01F0                    	add	ax,si
  3195 0000120A 720D                    	jc	pct_buffover		; buffer overflow will occur
  3196 0000120C 3B06[0000]              	cmp	ax,[buffer_end]
  3197 00001210 7307                    	jae	pct_buffover		; buffer overflow will occur
  3198                                  
  3199                                  ; buffer will not overflow, do quick transfer code
  3200 00001212 1F                      	pop	ds					; ds -> source (i/o buffer)
  3201 00001213 D1E9                    	shr	cx,1				; convert byte to word count
  3202 00001215 F3A5                    	rep	movsw
  3203 00001217 EB0F                    	jmp	SHORT pct_transdone
  3204                                  
  3205                                  pct_buffover:
  3206 00001219 A1[0000]                	mov	ax,[buffer_end]		; ax holds constant, buffer end
  3207 0000121C 1F                      	pop	ds					; ds -> source (i/o buffer)
  3208                                  
  3209                                  pct_transloop:
  3210 0000121D 39C7                    	cmp	di,ax				; see if destination overflow
  3211 0000121F 73CB                    	jae	pct_dioverf			; yes
  3212                                  
  3213                                  pct_trans1:
  3214 00001221 39C6                    	cmp	si,ax				; see if source overflow
  3215 00001223 73CB                    	jae	pct_sioverf			; yes
  3216                                  
  3217                                  pct_trans2:
  3218 00001225 A4                      	movsb					; transfer a char
  3219 00001226 E2F5                    	loop	pct_transloop	; loop through all chars to transfer
  3220                                  
  3221                                  pct_transdone:
  3222 00001228 1F                      	pop	ds					; restore critical registers
  3223                                  
  3224                                  ; adjust relocation table as well
  3225 00001229 8B0E[0000]              	mov	cx,[data_fixup_count]
  3226 0000122D E312                    	jcxz	pct_compdone	; no relocation entries
  3227 0000122F BE[0000]                	mov	si,OFFSET data_fixup_flag wrt DGROUP
  3228 00001232 A1[2600]                	mov	ax,[reloc_lowwater]	; get low water mark for shifting relocation entries
  3229                                  
  3230                                  pct_relloop:
  3231 00001235 3B04                    	cmp	ax,[si]				; see if relocation entry location was shifted
  3232 00001237 7703                    	ja	pct_nextrel			; no
  3233 00001239 832C10                  	sub	WORD PTR [si],10h	; shift relocation entry down one para
  3234                                  
  3235                                  pct_nextrel:
  3236 0000123C 83C602                  	add	si,2				; move to next entry, if any
  3237 0000123F E2F4                    	loop	pct_relloop
  3238                                  
  3239                                  pct_compdone:
  3240 00001241 59                      	pop	cx
  3241 00001242 5E                      	pop	si
  3242 00001243 B81000                  	mov	ax,16				; use as constant
  3243 00001246 29C2                    	sub	dx,ax				; drop count of bytes in LEDATA data
  3244 00001248 2906[2600]              	sub	[reloc_lowwater],ax	; adjust relocation low water mark for transfer
  3245 0000124C 29C6                    	sub	si,ax				; adjust si for transfer
  3246 0000124E 7304                    	jnc	pct_nocomp			; no carry (no buffer wrap)
  3247 00001250 0336[0000]              	add	si,[buffer_end]		; adjust for buffer wrap
  3248                                  
  3249                                  pct_nocomp:
  3250 00001254 83C303                  	add	bx,3				; move to next symbol table entry, if any
  3251 00001257 B81000                  	mov	ax,16				; use as constant
  3252 0000125A 0106[2600]              	add	[reloc_lowwater],ax	; adjust low water mark
  3253 0000125E 29C1                    	sub	cx,ax				; drop count of data bytes
  3254 00001260 01C6                    	add	si,ax				; point to next entry
  3255 00001262 7206                    	jc	pcs_of1				; overflow
  3256 00001264 3B36[0000]              	cmp	si,[buffer_end]		; see if past buffer
  3257 00001268 7204                    	jb	pct_donechk			; no
  3258                                  
  3259                                  ; buffer wrap/overflow
  3260                                  pcs_of1:
  3261 0000126A 2B36[0000]              	sub	si,[buffer_end]
  3262                                  
  3263                                  pct_donechk:
  3264 0000126E E303                    	jcxz	pct_done		; no more
  3265 00001270 E950FF                  	jmp	NEAR PTR pct_comploop
  3266                                  
  3267                                  pct_done:
  3268 00001273 A1[0000]                	mov	ax,[rec_offset]		; adjust data_offset with new LEDATA length
  3269 00001276 2906[0000]              	sub	WORD PTR [data_offset],ax
  3270 0000127A 831E[0200]00            	sbb	WORD [data_offset+2],0
  3271 0000127F A1[2400]                	mov	ax,[new_ledata_offset]	; get new LEDATA offset after previous compression
  3272 00001282 0106[0000]              	add	WORD PTR [data_offset],ax
  3273 00001286 8316[0200]00            	adc	WORD [data_offset+2],0
  3274 0000128B 0116[2400]              	add	[new_ledata_offset],dx	; save new next LEDATA offset after compression
  3275                                  
  3276 0000128F 89D1                    	mov	cx,dx				; get count of data bytes after compression
  3277 00001291 07                      	pop	es					; restore critical register
  3278 00001292 5E                      	pop	si
  3279 00001293 C3                      	ret
  3280                                  process_symbol_table	ENDP
  3281                                  
  3282                                  ;*****************************
  3283                                  ;* COMPSYM_FIXUP             *
  3284                                  ;*****************************
  3285                                  
  3286                                  ; fixup of compressed symbols
  3287                                  ; upon entry data_rec_offset holds position of fixup within LEDATA image,
  3288                                  ;  rec_offset holds offset of LEDATA data record
  3289                                  ; returns carry flag set if discard fixup, reset otherwise
  3290                                  ; destroys ax,bx,dx
  3291                                  
  3292                                  compsym_fixup	PROC
  3293 00001294 51                      	push	cx				; save critical register
  3294 00001295 06                      	push	es
  3295 00001296 8B1E[0000]              	mov	bx,[data_rec_offset]
  3296 0000129A 031E[0000]              	add	bx,[rec_offset]
  3297 0000129E 80E3F0                  	and	bl,0f0h				; mask off low bits
  3298 000012A1 B103                    	mov	cl,3
  3299 000012A3 D3EB                    	shr	bx,cl				; bx contains symbol number of fixup, word offset
  3300 000012A5 89D9                    	mov	cx,bx
  3301 000012A7 D1E9                    	shr	cx,1
  3302 000012A9 01CB                    	add	bx,cx				; make 3-byte offset
  3303 000012AB 83C30C                  	add	bx,12				; adjust past system bytes
  3304                                  
  3305 000012AE 8E06[0000]              	mov	es,[current_clipmod_ptr]	; [es:bx] -> symbol table count/offset
  3306 000012B2 26F6470220              	test	BYTE PTR [es:bx+2],20h	; see if compressed symbol
  3307 000012B7 7403                    	je	cf_nocomp			; no
  3308                                  
  3309                                  ; compressed symbol, trash fixup
  3310                                  cf_comp:
  3311 000012B9 F9                      	stc						; set carry flag to indicate discard fixup
  3312 000012BA EB01                    	jmp	SHORT cf_ret
  3313                                  
  3314                                  cf_nocomp:
  3315 000012BC F8                      	clc
  3316                                  
  3317                                  cf_ret:
  3318 000012BD 07                      	pop	es					; restore critical register
  3319 000012BE 59                      	pop	cx
  3320 000012BF C3                      	ret
  3321                                  compsym_fixup	ENDP
  3322                                  
  3323                                  ;***** END WORK
  3324                                  
  3325                                  END
