     1                                  
     2                                  ; Public Domain
     3                                  
     4                                  ; test install command: install; amismsg; amismsg uninstall
     5                                  ; test run command: ; .; .
     6                                  
     7                                  %include "lmacros3.mac"
     1                              <1> [list -]
    14                              <2> [list -]
    14                              <1> [list -]
     8                                  %include "eld.mac"
     1                              <1> %if 0
     2                              <1> 
     3                              <1> Extensions for lDebug macros
     4                              <1> 
     5                              <1> Copyright (C) 2008-2025 E. C. Masloch
     6                              <1> 
     7                              <1> Usage of the works is permitted provided that this
     8                              <1> instrument is retained with the works, so that any entity
     9                              <1> that uses the works is notified of this instrument.
    10                              <1> 
    11                              <1> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <1> 
    13                              <1> %endif
    14                              <1> 
    15                              <1> %ifndef ELD_MAC
    16                              <1> %define ELD_MAC 1
    17                              <1> 
    18                              <1> %include "lmacros3.mac"
     1                              <2> [list -]
    19                              <1> 
    20                              <1> 		; ELD executable header
    21                              <1> 	struc ELD_HEADER
    22 00000000 ????????            <1> eldhSignature:		resb 4	; "ELD1"
    23 00000004 ??????              <1> 			resb 3	; reserved
    24 00000007 ??                  <1> 			resb 1	; 26 (Ctrl-Z)
    25 00000008 ????????            <1> eldhCodeOffset:		resd 1	; position displacement from eldhSignature
    26 0000000C ????                <1> eldhCodeImageLength:	resw 1	; amount bytes, at least 32
    27 0000000E ????                <1> eldhCodeAllocLength:	resw 1	; amount bytes, added to prior. sum < 64 KiB
    28 00000010 ????????            <1> eldhDataOffset:		resd 1
    29 00000014 ????                <1> eldhDataImageLength:	resw 1	; (zero allowed)
    30 00000016 ????                <1> eldhDataAllocLength:	resw 1	; (zero allowed)
    31 00000018 ????                <1> eldhCodeEntrypoint:	resw 1	; within code section, used as displacement
    32 0000001A ????????            <1> eldhReserved:		resb 4	; reserved
    33 0000001E ????                <1> eldhExtensionSize:	resw 1	; from eldhSignature, -> past eldhx fields in use
    34                              <1> 	endstruc
    35                              <1> 	endarea ELD_HEADER, 1
    36                              <1> 
    37                              <1> 	struc ELD_HEADERX
    38 00000000 <res 20h>           <1> eldhxHeader:		resb ELD_HEADER_size
    39 00000020 ????????            <1> eldhxDescriptionOffset:	resd 1	; zero if none, from eldhxHeader. <= 128 Bytes
    40 00000024 ????????            <1> eldhxHelpOffset:	resd 1	; zero if none, from eldhxHeader
    41 00000028 ????????            <1> eldhxLibTable:		resd 1	; zero if none, from eldhxHeader
    42 0000002C ????????            <1> eldhxDateTimeOffset:	resd 1	; zero if none, from eldhxHeader
    43                              <1> 	alignb 16
    44                              <1> 	endstruc
    45                              <1> 
    46                              <1> 	struc ELD_TRAILER_HEADER
    47 00000000 ????????????????    <1> eldthSignature:		resb 8	; "ELD1TAIL"
    48 00000008 ????????            <1> eldthHeaderOffset:	resd 1	; negative displacement from eldthSignature,
    49                              <1> 				;  add this dword to the seek offset
    50 0000000C ????                <1> eldthReserved:		resw 1	; reserved, must be initialised to zero
    51 0000000E ????                <1> eldthChecksum:		resw 1	; sum of all words in trailer header = 0
    52                              <1> 	endstruc
    53                              <1> 	endarea ELD_TRAILER_HEADER, 1
    54                              <1> 
    55                              <1> 	struc ELD_LIBTABLE
    56 00000000 ????                <1> eldltFormat:		resw 1
    57                              <1> 	; 0 = uncompressed
    58                              <1> 	; 2 = heatshrink compressed
    59                              <1> 	; 3 = lzexedat -4 compressed
    60                              <1> 	; 4 = lzexedat -4 -l compressed
    61 00000002 ????                <1> eldltAmount:		resw 1
    62 00000004 ????????            <1> eldltOffset:		resd 1	; from eldhxHeader
    63                              <1> eldltCompressedLength:		; (dword, only present if format 2, 3, or 4)
    64                              <1> 	endstruc
    65                              <1> 	endarea ELD_LIBTABLE, 1
    66                              <1> 
    67                              <1> 		; ELD instance header
    68                              <1> 	struc ELD_INSTANCE
    69 00000000 ????                <1> eldiStartCode:		resw 1	; -> this structure itself (para aligned)
    70 00000002 ????                <1> eldiEndCode:		resw 1	; -> behind memory used by instance (para aligned)
    71 00000004 ????                <1> eldiStartData:		resw 1	; -> data in data entry section (para aligned), or 0
    72 00000006 ????                <1> eldiEndData:		resw 1	; -> behind data (para aligned), or 0
    73 00000008 ????????????????    <1> eldiIdentifier:		resb 8	; blank-filled text
    74 00000010 ????                <1> eldiFlags:		resw 1	; flags
    75                              <1> eldiListing_size equ 14
    76 00000012 <res Eh>            <1> eldiListing:		resb eldiListing_size
    77                              <1> 				; ASCIZ listing file name
    78                              <1> 	endstruc
    79                              <1> 		; flags for eldiFlags:
    80                              <1> eldifResident:		equ 1
    81                              <1> 
    82                              <1> 		; ELD link info header
    83                              <1> 	struc ELD_LINKINFO
    84 00000000 ????                <1> eldlSignature:		resw 1	; 0E1D1h
    85 00000002 ????????            <1> eldlReserved:		resw 2
    86 00000006 ????                <1> eldlUseLinkHash:	resw 1
    87 00000008 ????                <1> eldlDataAmount:		resw 1
    88 0000000A ????                <1> eldlDataPrefixes:	resw 1
    89 0000000C ????                <1> eldlDataEntries:	resw 1
    90 0000000E ????                <1> eldlDataAddresses:	resw 1
    91 00000010 ????                <1> eldlCodeAmount:		resw 1
    92 00000012 ????                <1> eldlCodePrefixes:	resw 1
    93 00000014 ????                <1> eldlCodeEntries:	resw 1
    94 00000016 ????                <1> eldlCodeAddresses:	resw 1
    95                              <1> 	endstruc
    96                              <1> 
    97                              <1> 	numdef ELD_CODE_VSTART, 9001h
    98                              <1> 	numdef ELD_DATA_VSTART, 8000h
    99                              <1> 	numdef ELD_RELOC_VSTART, 8000h
   100                              <1> 
   101                              <1> 	numdef ELD_RECLAIM_HINT, 0
   102                              <1> 	strdef ELD_LISTING, ""
   103                              <1> 	numdef ELD_DATETIME, 0
   104                              <1> 
   105                              <1> %if _ELD_DATETIME
   106                              <1>  %define PUT_ELDHX_DATETIME_OFFSET at eldhxDateTimeOffset, dd DATAOFFSET + datetime - datastart
   107                              <1>  %macro PUT_ELD_DATETIME 0.nolist
   108                              <1> datetime:	asciz __UTC_DATE__,'T',__UTC_TIME__,'Z'
   109                              <1> 		asciz		; for future extension
   110                              <1>  %endmacro
   111                              <1> %else
   112                              <1>  %define PUT_ELDHX_DATETIME_OFFSET
   113                              <1>  %define PUT_ELD_DATETIME
   114                              <1> %endif
   115                              <1> 
   116                              <1> %endif
     9                                  %include "eldcall.mac"
     1                              <1> %if 0
     2                              <1> 
     3                              <1> Extensions for lDebug call macros
     4                              <1> 
     5                              <1> Copyright (C) 2008-2024 E. C. Masloch
     6                              <1> 
     7                              <1> Usage of the works is permitted provided that this
     8                              <1> instrument is retained with the works, so that any entity
     9                              <1> that uses the works is notified of this instrument.
    10                              <1> 
    11                              <1> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <1> 
    13                              <1> %endif
    14                              <1> 
    15                              <1> %ifndef ELDCALL_MAC
    16                              <1> %define ELDCALL_MAC 1
    17                              <1> 
    18                              <1> %include "lmacros3.mac"
     1                              <2> [list -]
    19                              <1> %include "nasmhash.mac"
     1                              <2> 
     2                              <2> %if 0
     3                              <2> 
     4                              <2> Hashing macros
     5                              <2>  by E. C. Masloch, 2019
     6                              <2> 
     7                              <2> Usage of the works is permitted provided that this
     8                              <2> instrument is retained with the works, so that any entity
     9                              <2> that uses the works is notified of this instrument.
    10                              <2> 
    11                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <2> 
    13                              <2> %endif
    14                              <2> 
    15                              <2> %ifndef __NASMHASH_MAC__
    16                              <2> %assign __NASMHASH_MAC__ 1
    17                              <2> 
    18                              <2> 
    19                              <2> 	%macro hashdef 2+.nolist
    20                              <2> %ifempty %2
    21                              <2>  %assign _%1 1
    22                              <2> %else
    23                              <2> %ifstr %2
    24                              <2>  %define %%string %2
    25                              <2> %elifid %2
    26                              <2>  %defstr %%string %2
    27                              <2> %elifnum %2
    28                              <2>  %defstr %%string %2
    29                              <2> %eliftok %2
    30                              <2>  %defstr %%string %2
    31                              <2> %else
    32                              <2>  %error Unknown input
    33                              <2> %endif
    34                              <2> %strlen %%length %%string
    35                              <2> %assign %%hash 1
    36                              <2> %assign %%index 1
    37                              <2> %rep %%length
    38                              <2>  %substr %%char %%string %%index
    39                              <2>  %assign %%hash (%%hash * 31 + %%char) & 0FFFFh
    40                              <2>  %assign %%index %%index + 1
    41                              <2> %endrep
    42                              <2> %assign _%1 %%hash
    43                              <2> %endif
    44                              <2> 	%endmacro
    45                              <2> 
    46                              <2> 
    47                              <2> %endif
    20                              <1> %include "elddata.mac"
     1                              <2> %if 0
     2                              <2> 
     3                              <2> Extensions for lDebug data relocation macros
     4                              <2> 
     5                              <2> Copyright (C) 2008-2024 E. C. Masloch
     6                              <2> 
     7                              <2> Usage of the works is permitted provided that this
     8                              <2> instrument is retained with the works, so that any entity
     9                              <2> that uses the works is notified of this instrument.
    10                              <2> 
    11                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <2> 
    13                              <2> %endif
    14                              <2> 
    15                              <2> %ifndef ELDDATA_MAC
    16                              <2> %define ELDDATA_MAC 1
    17                              <2> 
    18                              <2> %include "lmacros3.mac"
     1                              <3> [list -]
    19                              <2> %include "nasmhash.mac"
     1                              <3> 
     2                              <3> %if 0
     3                              <3> 
     4                              <3> Hashing macros
     5                              <3>  by E. C. Masloch, 2019
     6                              <3> 
     7                              <3> Usage of the works is permitted provided that this
     8                              <3> instrument is retained with the works, so that any entity
     9                              <3> that uses the works is notified of this instrument.
    10                              <3> 
    11                              <3> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <3> 
    13                              <3> %endif
    14                              <3> 
    15                              <3> %ifndef __NASMHASH_MAC__
    16                              <3> %assign __NASMHASH_MAC__ 1
    17                              <3> 
    18                              <3> 
    19                              <3> 	%macro hashdef 2+.nolist
    20                              <3> %ifempty %2
    21                              <3>  %assign _%1 1
    22                              <3> %else
    23                              <3> %ifstr %2
    24                              <3>  %define %%string %2
    25                              <3> %elifid %2
    26                              <3>  %defstr %%string %2
    27                              <3> %elifnum %2
    28                              <3>  %defstr %%string %2
    29                              <3> %eliftok %2
    30                              <3>  %defstr %%string %2
    31                              <3> %else
    32                              <3>  %error Unknown input
    33                              <3> %endif
    34                              <3> %strlen %%length %%string
    35                              <3> %assign %%hash 1
    36                              <3> %assign %%index 1
    37                              <3> %rep %%length
    38                              <3>  %substr %%char %%string %%index
    39                              <3>  %assign %%hash (%%hash * 31 + %%char) & 0FFFFh
    40                              <3>  %assign %%index %%index + 1
    41                              <3> %endrep
    42                              <3> %assign _%1 %%hash
    43                              <3> %endif
    44                              <3> 	%endmacro
    45                              <3> 
    46                              <3> 
    47                              <3> %endif
    20                              <2> %include "eldcheck.mac"
     1                              <3> %if 0
     2                              <3> 
     3                              <3> Extensions for lDebug relocation check macros
     4                              <3> 
     5                              <3> Copyright (C) 2008-2023 E. C. Masloch
     6                              <3> 
     7                              <3> Usage of the works is permitted provided that this
     8                              <3> instrument is retained with the works, so that any entity
     9                              <3> that uses the works is notified of this instrument.
    10                              <3> 
    11                              <3> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <3> 
    13                              <3> %endif
    14                              <3> 
    15                              <3> %ifndef ELDCHECK_MAC
    16                              <3> %define ELDCHECK_MAC 1
    17                              <3> 
    18                              <3> %assign ELDSTRICT 0
    19                              <3> %assign ELDSTRICTCOUNTER 0
    20                              <3> 
    21                              <3> 	%imacro eldstrict 1.nolist
    22                              <3> %ifidni %1, on
    23                              <3>  %assign ELDSTRICT 1
    24                              <3>  [warning +error=reloc-abs]
    25                              <3>  [warning +reloc-abs]
    26                              <3> %elifidni %1, off
    27                              <3>  %assign ELDSTRICT 0
    28                              <3>  [warning -reloc-abs]
    29                              <3> %else
    30                              <3>  %error Unknown keyword
    31                              <3> %endif
    32                              <3> 	%endmacro
    33                              <3> 
    34                              <3> 	%imacro reloc 1+.nolist
    35                              <3> %if ELDSTRICT
    36                              <3>  %if ELDSTRICTCOUNTER
    37                              <3>   %error Missing relocation
    38                              <3>  %endif
    39                              <3>  [warning -reloc-abs]
    40                              <3>  %assign ELDSTRICTCOUNTER 1
    41                              <3> %endif
    42                              <3> %1
    43                              <3> 	%endmacro
    44                              <3> 
    45                              <3> 	%imacro reloc2 1+.nolist
    46                              <3> %if ELDSTRICT
    47                              <3>  %if ELDSTRICTCOUNTER
    48                              <3>   %error Missing relocation
    49                              <3>  %endif
    50                              <3>  [warning -reloc-abs]
    51                              <3>  %assign ELDSTRICTCOUNTER 2
    52                              <3> %endif
    53                              <3> %1
    54                              <3> 	%endmacro
    55                              <3> 
    56                              <3> 	%imacro eldstrictcheck 0.nolist
    57                              <3> %if ELDSTRICT
    58                              <3>  %ifn ELDSTRICTCOUNTER
    59                              <3>   %error Unexpected relocation
    60                              <3>  %else
    61                              <3>   %assign ELDSTRICTCOUNTER ELDSTRICTCOUNTER - 1
    62                              <3>   %ifn ELDSTRICTCOUNTER
    63                              <3>    [warning +reloc-abs]
    64                              <3>   %endif
    65                              <3>  %endif
    66                              <3> %endif
    67                              <3> 	%endmacro
    68                              <3> 
    69                              <3> %endif
    70                              <3> 
    21                              <2> 
    22                              <2> 
    23                              <2> %assign ELDLINKER 0
    24                              <2> 
    25                              <2> %define INTERNAL_CODE_TO_CODE_RELOCATIONS ""
    26                              <2> %define INTERNAL_CODE_TO_DATA_RELOCATIONS ""
    27                              <2> %define INTERNAL_DATA_TO_CODE_RELOCATIONS ""
    28                              <2> %define INTERNAL_DATA_TO_DATA_RELOCATIONS ""
    29                              <2> %define INTERNAL_LINKER_CODE_TO_CODE_RELOCATIONS ""
    30                              <2> %define INTERNAL_LINKER_CODE_TO_DATA_RELOCATIONS ""
    31                              <2> %define INTERNAL_LINKER_DATA_TO_CODE_RELOCATIONS ""
    32                              <2> %define INTERNAL_LINKER_DATA_TO_DATA_RELOCATIONS ""
    33                              <2> %assign ELDDATA_OPTIONAL_STATUS 0		; not any seen yet
    34                              <2> %assign ELDDATA_PMREQUIRED_STATUS 0		; not any seen yet
    35                              <2> %assign ELDDATA_NEXT_STATUS 0			; not any seen yet
    36                              <2> %assign ELDDATA_NEXT_ENTRY -1
    37                              <2> %assign ELDDATA_NEXT_SECTION -1
    38                              <2> %assign ELDDATA_NEXT_OTHER -1
    39                              <2> 
    40                              <2> 	%imacro internalcoderelocation 0-1.nolist -2
    41                              <2> %assign %%entry $ + _CURRENT_SECTION %+ FIXUP + %1
    42                              <2> %if ELDLINKER
    43                              <2>  %ifidni _CURRENT_SECTION_TYPE, DATA
    44                              <2>   %xdefine INTERNAL_LINKER_DATA_TO_CODE_RELOCATIONS INTERNAL_LINKER_DATA_TO_CODE_RELOCATIONS, %%entry
    45                              <2>  %else
    46                              <2>   %xdefine INTERNAL_LINKER_CODE_TO_CODE_RELOCATIONS INTERNAL_LINKER_CODE_TO_CODE_RELOCATIONS, %%entry
    47                              <2>  %endif
    48                              <2> %else
    49                              <2>  %ifidni _CURRENT_SECTION_TYPE, DATA
    50                              <2>   %xdefine INTERNAL_DATA_TO_CODE_RELOCATIONS INTERNAL_DATA_TO_CODE_RELOCATIONS, %%entry
    51                              <2>  %else
    52                              <2>   %xdefine INTERNAL_CODE_TO_CODE_RELOCATIONS INTERNAL_CODE_TO_CODE_RELOCATIONS, %%entry
    53                              <2>  %endif
    54                              <2> %endif
    55                              <2> 	eldstrictcheck
    56                              <2> 	%endmacro
    57                              <2> 
    58                              <2> 	%imacro internaldatarelocation 0-1.nolist -2
    59                              <2> %assign %%entry $ + _CURRENT_SECTION %+ FIXUP + %1
    60                              <2> %if ELDLINKER
    61                              <2>  %ifidni _CURRENT_SECTION_TYPE, DATA
    62                              <2>   %xdefine INTERNAL_LINKER_DATA_TO_DATA_RELOCATIONS INTERNAL_LINKER_DATA_TO_DATA_RELOCATIONS, %%entry
    63                              <2>  %else
    64                              <2>   %xdefine INTERNAL_LINKER_CODE_TO_DATA_RELOCATIONS INTERNAL_LINKER_CODE_TO_DATA_RELOCATIONS, %%entry
    65                              <2>  %endif
    66                              <2> %else
    67                              <2>  %ifidni _CURRENT_SECTION_TYPE, DATA
    68                              <2>   %xdefine INTERNAL_DATA_TO_DATA_RELOCATIONS INTERNAL_DATA_TO_DATA_RELOCATIONS, %%entry
    69                              <2>  %else
    70                              <2>   %xdefine INTERNAL_CODE_TO_DATA_RELOCATIONS INTERNAL_CODE_TO_DATA_RELOCATIONS, %%entry
    71                              <2>  %endif
    72                              <2> %endif
    73                              <2> 	eldstrictcheck
    74                              <2> 	%endmacro
    75                              <2> 
    76                              <2> ; dw INTERNAL_LINKER_CODE_TO_CODE_RELOCATIONS, 0
    77                              <2> ; dw INTERNAL_LINKER_CODE_TO_DATA_RELOCATIONS, 0
    78                              <2> ; dw INTERNAL_LINKER_DATA_TO_CODE_RELOCATIONS, -1
    79                              <2> ; dw INTERNAL_LINKER_DATA_TO_DATA_RELOCATIONS, -1
    80                              <2> ; dw INTERNAL_CODE_TO_CODE_RELOCATIONS, 0
    81                              <2> ; dw INTERNAL_CODE_TO_DATA_RELOCATIONS, 0
    82                              <2> ; dw INTERNAL_DATA_TO_CODE_RELOCATIONS, -1
    83                              <2> ; dw INTERNAL_DATA_TO_DATA_RELOCATIONS, -1
    84                              <2> 
    85                              <2> 
    86                              <2> %define LINK_DATA_RELOCATIONS ""
    87                              <2> %define LINK_LINKER_DATA_RELOCATIONS ""
    88                              <2> %define LINK_DATA_NAMES db ""
    89                              <2> %define LINK_DATA_DETECTION none, none
    90                              <2> 
    91                              <2> %define LINK_OTHER_DATA_RELOCATIONS ""
    92                              <2> %define LINK_OTHER_LINKER_DATA_RELOCATIONS ""
    93                              <2> %define LINK_OTHER_DATA_NAMES db ""
    94                              <2> %define LINK_OTHER_DATA_DETECTION none, none
    95                              <2> 
    96                              <2> %ifndef ELDOTHER
    97                              <2>  %assign ELDOTHER 0
    98                              <2> %endif
    99                              <2> %assign ELDOTHERLINK 0
   100                              <2> 
   101                              <2> 	%imacro otherlinkdatarelocation 1-3.nolist -2, required
   102                              <2> %if ELDOTHER
   103                              <2>  %assign ELDOTHERLINK 1
   104                              <2> %endif
   105                              <2> 	linkdatarelocation %1, %2, %3
   106                              <2> %assign ELDOTHERLINK 0
   107                              <2> 	%endmacro
   108                              <2> 
   109                              <2> 	%imacro linkdatarelocation 1-4.nolist -2, required, single
   110                              <2> %assign %%entry $ + _CURRENT_SECTION %+ FIXUP + %2
   111                              <2> %ifidni %3, required
   112                              <2>  %assign %%optional 0
   113                              <2> %elifidni %3, optional
   114                              <2>  %assign %%optional 100h
   115                              <2>  %if ELDDATA_OPTIONAL_STATUS == 0
   116                              <2>   %assign ELDDATA_OPTIONAL_STATUS 1
   117                              <2>  %elif ELDDATA_OPTIONAL_STATUS == 1
   118                              <2>  %else
   119                              <2>   %error Optional data link not allowed here
   120                              <2>  %endif
   121                              <2> %elifidni %3, PM required
   122                              <2>  %assign %%optional 300h
   123                              <2>  %assign ELDDATA_PMREQUIRED_STATUS 1
   124                              <2>  %if ELDDATA_OPTIONAL_STATUS == 0
   125                              <2>   %assign ELDDATA_OPTIONAL_STATUS 1
   126                              <2>  %elif ELDDATA_OPTIONAL_STATUS == 1
   127                              <2>  %else
   128                              <2>   %error Optional data link not allowed here
   129                              <2>  %endif
   130                              <2> %else
   131                              <2>  %fatal Unknown optional keyword
   132                              <2> %endif
   133                              <2> %ifidni _CURRENT_SECTION_TYPE, DATA
   134                              <2>  %assign %%DATASECTION 1
   135                              <2> %else
   136                              <2>  %assign %%DATASECTION 0
   137                              <2> %endif
   138                              <2> %ifidni %4, single
   139                              <2>  %if ELDDATA_NEXT_STATUS == 1		; after next ?
   140                              <2>   %error Unexpected single data link after next data link
   141                              <2>  %elif ELDDATA_NEXT_STATUS == 2		; after last ?
   142                              <2>   %assign ELDDATA_NEXT_STATUS 3		; note single with next/last present
   143                              <2>  %endif
   144                              <2>  %assign %%next 0
   145                              <2> %elifidni %4, next
   146                              <2>  %if ELDDATA_NEXT_STATUS == 0		; no next/last yet ?
   147                              <2>   %assign ELDDATA_NEXT_STATUS 1		; in next
   148                              <2>  %elif ELDDATA_NEXT_STATUS == 2		; after last ?
   149                              <2>   %assign ELDDATA_NEXT_STATUS 1		; in next
   150                              <2>  %elif ELDDATA_NEXT_STATUS == 3		; after single ?
   151                              <2>   %assign ELDDATA_NEXT_STATUS 1		; in next
   152                              <2>  %elif ELDDATA_NEXT_STATUS == 1		; repeated next ?
   153                              <2>   %if ELDDATA_NEXT_ENTRY != %%entry 	|| ELDDATA_NEXT_SECTION != %%DATASECTION 	|| ELDDATA_NEXT_OTHER != ELDOTHERLINK
   156                              <2>    %error Unexpected next data link
   157                              <2>   %endif
   158                              <2>  %else
   159                              <2>   %error Next data link not allowed here
   160                              <2>  %endif
   161                              <2>  %ifn %%optional
   162                              <2>   %error Next data link only valid as optional or PM required
   163                              <2>  %endif
   164                              <2>  %assign %%next 400h
   165                              <2>  %assign ELDDATA_NEXT_ENTRY %%entry
   166                              <2>  %assign ELDDATA_NEXT_SECTION %%DATASECTION
   167                              <2>  %assign ELDDATA_NEXT_OTHER ELDOTHERLINK
   168                              <2> %elifidni %4, last
   169                              <2>  %if ELDDATA_NEXT_STATUS == 0		; no next/last yet ?
   170                              <2>   %error Next last data link not allowed here
   171                              <2>  %elif ELDDATA_NEXT_STATUS == 2		; after last ?
   172                              <2>   %error Next last data link not allowed here
   173                              <2>  %elif ELDDATA_NEXT_STATUS == 3		; after single ?
   174                              <2>   %error Next last data link not allowed here
   175                              <2>  %elif ELDDATA_NEXT_STATUS == 1		; after next ?
   176                              <2>   %if ELDDATA_NEXT_ENTRY != %%entry 	|| ELDDATA_NEXT_SECTION != %%DATASECTION 	|| ELDDATA_NEXT_OTHER != ELDOTHERLINK
   179                              <2>    %error Unexpected next data link
   180                              <2>   %endif
   181                              <2>   %assign ELDDATA_NEXT_STATUS 2		; note now after last
   182                              <2>  %else
   183                              <2>   %error Next data link not allowed here
   184                              <2>  %endif
   185                              <2>  %assign %%next 800h
   186                              <2>  %assign ELDDATA_NEXT_ENTRY -1
   187                              <2>  %assign ELDDATA_NEXT_SECTION -1
   188                              <2> %else
   189                              <2>  %fatal Unknown next keyword
   190                              <2> %endif
   191                              <2> 	%if ELDOTHERLINK
   192                              <2> %if ELDLINKER
   193                              <2>  %xdefine LINK_OTHER_LINKER_DATA_RELOCATIONS LINK_OTHER_LINKER_DATA_RELOCATIONS, 1 + %%DATASECTION + %%optional + %%next, %%entry, %%name
   194                              <2> %else
   195                              <2>  %xdefine LINK_OTHER_DATA_RELOCATIONS LINK_OTHER_DATA_RELOCATIONS, 1 + %%DATASECTION + %%optional + %%next, %%entry, %%name
   196                              <2> %endif
   197                              <2> 	%else
   198                              <2> %if ELDLINKER
   199                              <2>  %xdefine LINK_LINKER_DATA_RELOCATIONS LINK_LINKER_DATA_RELOCATIONS, 1 + %%DATASECTION + %%optional + %%next, %%entry, %%name
   200                              <2> %else
   201                              <2>  %xdefine LINK_DATA_RELOCATIONS LINK_DATA_RELOCATIONS, 1 + %%DATASECTION + %%optional + %%next, %%entry, %%name
   202                              <2> %endif
   203                              <2> 	%endif
   204                              <2> %defstr %%string %1
   205                              <2> %strlen %%length %%string
   206                              <2> %if %%length > 64
   207                              <2> 	; Could be increased, but mustn't exceed 127 bytes
   208                              <2> 	;  because flag 80h is used to mark optional links
   209                              <2> 	;  that failed to be matched.
   210                              <2>  %error Too long link name: %1
   211                              <2> %endif
   212                              <2> %define LINK_DATA_CHECK %1
   213                              <2> 	%if ELDOTHERLINK
   214                              <2> 	linkdata_detect LINK_OTHER_DATA_DETECTION
   215                              <2> %if LINK_DATA_NEW
   216                              <2>  %xdefine LINK_OTHER_DATA_DETECTION LINK_OTHER_DATA_DETECTION, %1, %%name
   217                              <2> 	hashdef HASH, %%string
   218                              <2>  %xdefine LINK_OTHER_DATA_NAMES 	LINK_OTHER_DATA_NAMES, %%name:, dw _HASH, {counted %%string}
   220                              <2> %else
   221                              <2>  %%name equ LINK_DATA_DUPLICATE
   222                              <2> %endif
   223                              <2> 	%else
   224                              <2> 	linkdata_detect LINK_DATA_DETECTION
   225                              <2> %if LINK_DATA_NEW
   226                              <2>  %xdefine LINK_DATA_DETECTION LINK_DATA_DETECTION, %1, %%name
   227                              <2> 	hashdef HASH, %%string
   228                              <2>  %xdefine LINK_DATA_NAMES 	LINK_DATA_NAMES, %%name:, dw _HASH, {counted %%string}
   230                              <2> %else
   231                              <2>  %%name equ LINK_DATA_DUPLICATE
   232                              <2> %endif
   233                              <2> 	%endif
   234                              <2> 	eldstrictcheck
   235                              <2> 	%endmacro
   236                              <2> 
   237                              <2> 	%imacro linkdata_detect 2-*.nolist
   238                              <2> %assign LINK_DATA_NEW 1
   239                              <2> %rep (%0 - 2) / 2
   240                              <2>  %rotate 2
   241                              <2>  %ifidni %1, LINK_DATA_CHECK
   242                              <2>   %assign LINK_DATA_NEW 0
   243                              <2>   %xdefine LINK_DATA_DUPLICATE %2
   244                              <2>   %exitrep
   245                              <2>  %endif
   246                              <2> %endrep
   247                              <2> 	%endmacro
   248                              <2> 
   249                              <2> 	%imacro link_data_dump_names 1-*.nolist
   250                              <2> %rep %0
   251                              <2> 	%1
   252                              <2>  %rotate 1
   253                              <2> %endrep
   254                              <2> 	%endmacro
   255                              <2> 
   256                              <2> ; dw LINK_LINKER_DATA_RELOCATIONS, 0, 0
   257                              <2> ; dw LINK_DATA_RELOCATIONS, 0, 0
   258                              <2> ; link_data_dump_names ELDCALL_CODE_NAMES
   259                              <2> 
   260                              <2> %endif
    21                              <1> 
    22                              <1> %assign ELDLINKER 0
    23                              <1> 
    24                              <1> [section relocatedzero nobits vstart=0]
    25                              <1> relocatedzero:
    26                              <1> __SECT__
    27                              <1> 
    28                              <1> 	numdef HOUDINI, 1
    29                              <1> 	numdef HOUDINI_CONDITIONAL, 1
    30                              <1> 
    31                              <1> %imacro houdini 0.nolist
    32                              <1> %if _HOUDINI
    33                              <1>  %if _HOUDINI_CONDITIONAL
    34                              <1> reloc	testopt [ss:relocateddata], 100h
    35                              <1> linkdatarelocation options7, -3
    36                              <1> 	jz %%skip
    37                              <1>  %endif
    38                              <1> reloc	testopt [ss:relocateddata], 100h
    39                              <1> linkdatarelocation internalflags6, -3
    40                              <1> 	jz %%skip
    41                              <1> 	int3
    42                              <1> %%skip:
    43                              <1> %endif
    44                              <1> %endmacro
    45                              <1> 
    46                              <1> %define ELDCALL_CODE_RELOCATIONS ""
    47                              <1> %define ELDCALL_LINKER_CODE_RELOCATIONS ""
    48                              <1> %define ELDCALL_CODE_RELOCATIONS_OPTIONAL ""
    49                              <1> %define ELDCALL_LINKER_CODE_RELOCATIONS_OPTIONAL ""
    50                              <1> %define ELDCALL_CODE_NAMES db ""
    51                              <1> %define ELDCALL_CODE_DETECTION none, none
    52                              <1> %assign ELDCALL_OPTIONAL_STATUS 0		; not any seen yet
    53                              <1> %assign ELDCALL_PMREQUIRED_STATUS 0		; not any seen yet
    54                              <1> %assign ELDCALL_NEXT_STATUS 0			; not any seen yet
    55                              <1> %assign ELDCALL_NEXT_ENTRY -1
    56                              <1> 
    57                              <1> 	%imacro extcall 1-3.nolist required, single
    58                              <1> %ifidni _CURRENT_SECTION_TYPE, DATA
    59                              <1>  %error "ELD call cannot be used in ELD data block"
    60                              <1> %endif
    61                              <1> %assign %%entry $ + _CURRENT_SECTION %+ FIXUP
    62                              <1> %ifidni %2, required
    63                              <1>  %assign %%optional 0
    64                              <1> %elifidni %2, optional
    65                              <1>  %assign %%optional 100h
    66                              <1>  %if ELDCALL_OPTIONAL_STATUS == 0
    67                              <1>   %assign ELDCALL_OPTIONAL_STATUS 1
    68                              <1>  %elif ELDCALL_OPTIONAL_STATUS == 1
    69                              <1>  %else
    70                              <1>   %error Optional code link not allowed here
    71                              <1>  %endif
    72                              <1> %elifidni %2, PM required
    73                              <1>  %assign %%optional 300h
    74                              <1>  %assign ELDCALL_PMREQUIRED_STATUS 1
    75                              <1>  %if ELDCALL_OPTIONAL_STATUS == 0
    76                              <1>   %assign ELDCALL_OPTIONAL_STATUS 1
    77                              <1>  %elif ELDCALL_OPTIONAL_STATUS == 1
    78                              <1>  %else
    79                              <1>   %error Optional code link not allowed here
    80                              <1>  %endif
    81                              <1> %else
    82                              <1>  %fatal Unknown optional keyword
    83                              <1> %endif
    84                              <1> %ifidni %3, single
    85                              <1>  %if ELDCALL_NEXT_STATUS == 1		; after next ?
    86                              <1>   %error Unexpected single code link after next code link
    87                              <1>  %elif ELDCALL_NEXT_STATUS == 2		; after last ?
    88                              <1>   %assign ELDCALL_NEXT_STATUS 3		; note single with next/last present
    89                              <1>  %endif
    90                              <1>  %assign %%next 0
    91                              <1> %elifidni %3, next
    92                              <1>  %if ELDCALL_NEXT_STATUS == 0		; no next/last yet ?
    93                              <1>   %assign ELDCALL_NEXT_STATUS 1		; in next
    94                              <1>  %elif ELDCALL_NEXT_STATUS == 2		; after last ?
    95                              <1>   %assign ELDCALL_NEXT_STATUS 1		; in next
    96                              <1>  %elif ELDCALL_NEXT_STATUS == 3		; after single ?
    97                              <1>   %assign ELDCALL_NEXT_STATUS 1		; in next
    98                              <1>  %elif ELDCALL_NEXT_STATUS == 1		; repeated next ?
    99                              <1>   %if ELDCALL_NEXT_ENTRY != %%entry
   100                              <1>    %error Unexpected next code link
   101                              <1>   %endif
   102                              <1>  %else
   103                              <1>   %error Next code link not allowed here
   104                              <1>  %endif
   105                              <1>  %ifn %%optional
   106                              <1>   %error Next code link only valid as optional or PM required
   107                              <1>  %endif
   108                              <1>  %assign %%next 400h
   109                              <1>  %assign ELDCALL_NEXT_ENTRY %%entry
   110                              <1> %elifidni %3, last
   111                              <1>  %if ELDCALL_NEXT_STATUS == 0		; no next/last yet ?
   112                              <1>   %error Next last code link not allowed here
   113                              <1>  %elif ELDCALL_NEXT_STATUS == 2		; after last ?
   114                              <1>   %error Next last code link not allowed here
   115                              <1>  %elif ELDCALL_NEXT_STATUS == 3		; after single ?
   116                              <1>   %error Next last code link not allowed here
   117                              <1>  %elif ELDCALL_NEXT_STATUS == 1		; after next ?
   118                              <1>   %if ELDCALL_NEXT_ENTRY != %%entry
   119                              <1>    %error Unexpected next code link
   120                              <1>   %endif
   121                              <1>   %assign ELDCALL_NEXT_STATUS 2		; note now after last
   122                              <1>  %else
   123                              <1>   %error Next code link not allowed here
   124                              <1>  %endif
   125                              <1>  %assign %%next 800h
   126                              <1>  %assign ELDCALL_NEXT_ENTRY -1
   127                              <1>  %assign ELDCALL_NEXT_SECTION -1
   128                              <1> %else
   129                              <1>  %fatal Unknown next keyword
   130                              <1> %endif
   131                              <1> %if %%next != 400h
   132                              <1> %if 0
   133                              <1> [warning -reloc-rel-word]
   134                              <1> 	call near relocatedzero
   135                              <1> [warning +reloc-rel-word]
   136                              <1> %else
   137                              <1> 	db 0E8h
   138                              <1> reloc	dw relocatedzero
   139                              <1> 	eldstrictcheck
   140                              <1> %endif
   141                              <1> 	jmp strict short %%skipparameter
   142                              <1> 	dw 0
   143                              <1> %%skipparameter:
   144                              <1> %endif
   145                              <1> %if ELDLINKER
   146                              <1>  %xdefine ELDCALL_LINKER_CODE_RELOCATIONS ELDCALL_LINKER_CODE_RELOCATIONS, %%entry, %%name
   147                              <1>  %xdefine ELDCALL_LINKER_CODE_RELOCATIONS_OPTIONAL ELDCALL_LINKER_CODE_RELOCATIONS_OPTIONAL, 1 + %%optional + %%next, %%entry, %%name
   148                              <1> %else
   149                              <1>  %xdefine ELDCALL_CODE_RELOCATIONS ELDCALL_CODE_RELOCATIONS, %%entry, %%name
   150                              <1>  %xdefine ELDCALL_CODE_RELOCATIONS_OPTIONAL ELDCALL_CODE_RELOCATIONS_OPTIONAL, 1 + %%optional + %%next, %%entry, %%name
   151                              <1> %endif
   152                              <1> %defstr %%string %1
   153                              <1> %strlen %%length %%string
   154                              <1> %if %%length > 64
   155                              <1> 	; Could be increased, but mustn't exceed 127 bytes
   156                              <1> 	;  because flag 80h is used to mark optional links
   157                              <1> 	;  that failed to be matched.
   158                              <1>  %error Too long link name: %1
   159                              <1> %endif
   160                              <1> %define ELDCALL_CODE_CHECK %1
   161                              <1> 	linkcode_detect ELDCALL_CODE_DETECTION
   162                              <1> %if ELDCALL_CODE_NEW
   163                              <1>  %xdefine ELDCALL_CODE_DETECTION ELDCALL_CODE_DETECTION, %1, %%name
   164                              <1> 	hashdef HASH, %%string
   165                              <1> %xdefine ELDCALL_CODE_NAMES 	ELDCALL_CODE_NAMES, %%name:, dw _HASH, {counted %%string}
   167                              <1> %else
   168                              <1>  %%name equ ELDCALL_CODE_DUPLICATE
   169                              <1> %endif
   170                              <1> 	%endmacro
   171                              <1> 
   172                              <1> 	%imacro linkcode_detect 2-*.nolist
   173                              <1> %assign ELDCALL_CODE_NEW 1
   174                              <1> %rep (%0 - 2) / 2
   175                              <1>  %rotate 2
   176                              <1>  %ifidni %1, ELDCALL_CODE_CHECK
   177                              <1>   %assign ELDCALL_CODE_NEW 0
   178                              <1>   %xdefine ELDCALL_CODE_DUPLICATE %2
   179                              <1>   %exitrep
   180                              <1>  %endif
   181                              <1> %endrep
   182                              <1> 	%endmacro
   183                              <1> 
   184                              <1> 
   185                              <1> %define ELDCALL_CALLCALL_LIST none
   186                              <1> %define ELDCALL_CALLCALL_PROCESSED_PRIOR ""
   187                              <1> 
   188                              <1> 	%imacro extcallcall 1.nolist
   189                              <1> 	call %1
   190                              <1> %xdefine ELDCALL_CALLCALL_LIST ELDCALL_CALLCALL_LIST, %1
   191                              <1> 	%endmacro
   192                              <1> 
   193                              <1> %assign ELDCALLCALL_DUMPED 0
   194                              <1> 
   195                              <1> 	%imacro eldcall_dump_callcall 1-*.nolist
   196                              <1> %xdefine ELDCALL_CALLCALL_PROCESSED ELDCALL_CALLCALL_PROCESSED_PRIOR
   197                              <1>  %rep %0 - 1
   198                              <1>   %rotate 1
   199                              <1>   %define ELDCALL_CHECK %1
   200                              <1> 	eldcall_callcall_detect ELDCALL_CALLCALL_PROCESSED
   201                              <1>   %if ELDCALL_NEW
   202                              <1>    %xdefine ELDCALL_CALLCALL_PROCESSED ELDCALL_CALLCALL_PROCESSED, %1
   203                              <1> 	align 8, nop
   204                              <1> %1:
   205                              <1> 	extcall %1
   206                              <1> 	retn
   207                              <1>   %endif
   208                              <1>  %endrep
   209                              <1> %assign ELDCALLCALL_DUMPED 1
   210                              <1> %define ELDCALL_CALLCALL_LIST none
   211                              <1> 	%endmacro
   212                              <1> 
   213                              <1> 	%imacro eldcall_new_callcall 0.nolist
   214                              <1> %if ELDCALLCALL_DUMPED
   215                              <1>  %xdefine ELDCALL_CALLCALL_PROCESSED_PRIOR   ELDCALL_CALLCALL_PROCESSED_PRIOR, ELDCALL_CALLCALL_PROCESSED
   217                              <1>  %assign ELDCALLCALL_DUMPED 0
   218                              <1>  %define ELDCALL_CALLCALL_LIST none
   219                              <1> %endif
   220                              <1> 	%endmacro
   221                              <1> 
   222                              <1> 	%imacro eldcall_callcall_detect 1-*.nolist
   223                              <1> %assign ELDCALL_NEW 1
   224                              <1> %rep %0
   225                              <1>  %ifidni %1, ELDCALL_CHECK
   226                              <1>   %assign ELDCALL_NEW 0
   227                              <1>   %exitrep
   228                              <1>  %endif
   229                              <1>  %rotate 1
   230                              <1> %endrep
   231                              <1> 	%endmacro
   232                              <1> 
   233                              <1> 	%imacro eldcall_dump_names 1-*.nolist
   234                              <1> %rep %0
   235                              <1> 	%1
   236                              <1>  %rotate 1
   237                              <1> %endrep
   238                              <1> 	%endmacro
   239                              <1> 
   240                              <1> ; eldcall_dump_callcall ELDCALL_CALLCALL_LIST
   241                              <1> ; if using optional code links:
   242                              <1> ;  dw ELDCALL_LINKER_CODE_RELOCATIONS_OPTIONAL, 0
   243                              <1> ;  dw ELDCALL_CODE_RELOCATIONS_OPTIONAL, 0
   244                              <1> ; if not using optional code links:
   245                              <1> ;  dw ELDCALL_LINKER_CODE_RELOCATIONS, 0, 0
   246                              <1> ;  dw ELDCALL_CODE_RELOCATIONS, 0, 0
   247                              <1> ; eldcall_dump_names ELDCALL_CODE_NAMES
   248                              <1> 
   249                              <1> %endif
    10                                  %include "elddata.mac"
     1                              <1> %if 0
     2                              <1> 
     3                              <1> Extensions for lDebug data relocation macros
     4                              <1> 
     5                              <1> Copyright (C) 2008-2024 E. C. Masloch
     6                              <1> 
     7                              <1> Usage of the works is permitted provided that this
     8                              <1> instrument is retained with the works, so that any entity
     9                              <1> that uses the works is notified of this instrument.
    10                              <1> 
    11                              <1> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <1> 
    13                              <1> %endif
    14                              <1> 
    15                              <1> %ifndef ELDDATA_MAC
    16                              <1> %define ELDDATA_MAC 1
    17                              <1> 
    18                              <1> %include "lmacros3.mac"
    19                              <1> %include "nasmhash.mac"
    20                              <1> %include "eldcheck.mac"
    21                              <1> 
    22                              <1> 
    23                              <1> %assign ELDLINKER 0
    24                              <1> 
    25                              <1> %define INTERNAL_CODE_TO_CODE_RELOCATIONS ""
    26                              <1> %define INTERNAL_CODE_TO_DATA_RELOCATIONS ""
    27                              <1> %define INTERNAL_DATA_TO_CODE_RELOCATIONS ""
    28                              <1> %define INTERNAL_DATA_TO_DATA_RELOCATIONS ""
    29                              <1> %define INTERNAL_LINKER_CODE_TO_CODE_RELOCATIONS ""
    30                              <1> %define INTERNAL_LINKER_CODE_TO_DATA_RELOCATIONS ""
    31                              <1> %define INTERNAL_LINKER_DATA_TO_CODE_RELOCATIONS ""
    32                              <1> %define INTERNAL_LINKER_DATA_TO_DATA_RELOCATIONS ""
    33                              <1> %assign ELDDATA_OPTIONAL_STATUS 0		; not any seen yet
    34                              <1> %assign ELDDATA_PMREQUIRED_STATUS 0		; not any seen yet
    35                              <1> %assign ELDDATA_NEXT_STATUS 0			; not any seen yet
    36                              <1> %assign ELDDATA_NEXT_ENTRY -1
    37                              <1> %assign ELDDATA_NEXT_SECTION -1
    38                              <1> %assign ELDDATA_NEXT_OTHER -1
    39                              <1> 
    40                              <1> 	%imacro internalcoderelocation 0-1.nolist -2
    41                              <1> %assign %%entry $ + _CURRENT_SECTION %+ FIXUP + %1
    42                              <1> %if ELDLINKER
    43                              <1>  %ifidni _CURRENT_SECTION_TYPE, DATA
    44                              <1>   %xdefine INTERNAL_LINKER_DATA_TO_CODE_RELOCATIONS INTERNAL_LINKER_DATA_TO_CODE_RELOCATIONS, %%entry
    45                              <1>  %else
    46                              <1>   %xdefine INTERNAL_LINKER_CODE_TO_CODE_RELOCATIONS INTERNAL_LINKER_CODE_TO_CODE_RELOCATIONS, %%entry
    47                              <1>  %endif
    48                              <1> %else
    49                              <1>  %ifidni _CURRENT_SECTION_TYPE, DATA
    50                              <1>   %xdefine INTERNAL_DATA_TO_CODE_RELOCATIONS INTERNAL_DATA_TO_CODE_RELOCATIONS, %%entry
    51                              <1>  %else
    52                              <1>   %xdefine INTERNAL_CODE_TO_CODE_RELOCATIONS INTERNAL_CODE_TO_CODE_RELOCATIONS, %%entry
    53                              <1>  %endif
    54                              <1> %endif
    55                              <1> 	eldstrictcheck
    56                              <1> 	%endmacro
    57                              <1> 
    58                              <1> 	%imacro internaldatarelocation 0-1.nolist -2
    59                              <1> %assign %%entry $ + _CURRENT_SECTION %+ FIXUP + %1
    60                              <1> %if ELDLINKER
    61                              <1>  %ifidni _CURRENT_SECTION_TYPE, DATA
    62                              <1>   %xdefine INTERNAL_LINKER_DATA_TO_DATA_RELOCATIONS INTERNAL_LINKER_DATA_TO_DATA_RELOCATIONS, %%entry
    63                              <1>  %else
    64                              <1>   %xdefine INTERNAL_LINKER_CODE_TO_DATA_RELOCATIONS INTERNAL_LINKER_CODE_TO_DATA_RELOCATIONS, %%entry
    65                              <1>  %endif
    66                              <1> %else
    67                              <1>  %ifidni _CURRENT_SECTION_TYPE, DATA
    68                              <1>   %xdefine INTERNAL_DATA_TO_DATA_RELOCATIONS INTERNAL_DATA_TO_DATA_RELOCATIONS, %%entry
    69                              <1>  %else
    70                              <1>   %xdefine INTERNAL_CODE_TO_DATA_RELOCATIONS INTERNAL_CODE_TO_DATA_RELOCATIONS, %%entry
    71                              <1>  %endif
    72                              <1> %endif
    73                              <1> 	eldstrictcheck
    74                              <1> 	%endmacro
    75                              <1> 
    76                              <1> ; dw INTERNAL_LINKER_CODE_TO_CODE_RELOCATIONS, 0
    77                              <1> ; dw INTERNAL_LINKER_CODE_TO_DATA_RELOCATIONS, 0
    78                              <1> ; dw INTERNAL_LINKER_DATA_TO_CODE_RELOCATIONS, -1
    79                              <1> ; dw INTERNAL_LINKER_DATA_TO_DATA_RELOCATIONS, -1
    80                              <1> ; dw INTERNAL_CODE_TO_CODE_RELOCATIONS, 0
    81                              <1> ; dw INTERNAL_CODE_TO_DATA_RELOCATIONS, 0
    82                              <1> ; dw INTERNAL_DATA_TO_CODE_RELOCATIONS, -1
    83                              <1> ; dw INTERNAL_DATA_TO_DATA_RELOCATIONS, -1
    84                              <1> 
    85                              <1> 
    86                              <1> %define LINK_DATA_RELOCATIONS ""
    87                              <1> %define LINK_LINKER_DATA_RELOCATIONS ""
    88                              <1> %define LINK_DATA_NAMES db ""
    89                              <1> %define LINK_DATA_DETECTION none, none
    90                              <1> 
    91                              <1> %define LINK_OTHER_DATA_RELOCATIONS ""
    92                              <1> %define LINK_OTHER_LINKER_DATA_RELOCATIONS ""
    93                              <1> %define LINK_OTHER_DATA_NAMES db ""
    94                              <1> %define LINK_OTHER_DATA_DETECTION none, none
    95                              <1> 
    96                              <1> %ifndef ELDOTHER
    97                              <1>  %assign ELDOTHER 0
    98                              <1> %endif
    99                              <1> %assign ELDOTHERLINK 0
   100                              <1> 
   101                              <1> 	%imacro otherlinkdatarelocation 1-3.nolist -2, required
   102                              <1> %if ELDOTHER
   103                              <1>  %assign ELDOTHERLINK 1
   104                              <1> %endif
   105                              <1> 	linkdatarelocation %1, %2, %3
   106                              <1> %assign ELDOTHERLINK 0
   107                              <1> 	%endmacro
   108                              <1> 
   109                              <1> 	%imacro linkdatarelocation 1-4.nolist -2, required, single
   110                              <1> %assign %%entry $ + _CURRENT_SECTION %+ FIXUP + %2
   111                              <1> %ifidni %3, required
   112                              <1>  %assign %%optional 0
   113                              <1> %elifidni %3, optional
   114                              <1>  %assign %%optional 100h
   115                              <1>  %if ELDDATA_OPTIONAL_STATUS == 0
   116                              <1>   %assign ELDDATA_OPTIONAL_STATUS 1
   117                              <1>  %elif ELDDATA_OPTIONAL_STATUS == 1
   118                              <1>  %else
   119                              <1>   %error Optional data link not allowed here
   120                              <1>  %endif
   121                              <1> %elifidni %3, PM required
   122                              <1>  %assign %%optional 300h
   123                              <1>  %assign ELDDATA_PMREQUIRED_STATUS 1
   124                              <1>  %if ELDDATA_OPTIONAL_STATUS == 0
   125                              <1>   %assign ELDDATA_OPTIONAL_STATUS 1
   126                              <1>  %elif ELDDATA_OPTIONAL_STATUS == 1
   127                              <1>  %else
   128                              <1>   %error Optional data link not allowed here
   129                              <1>  %endif
   130                              <1> %else
   131                              <1>  %fatal Unknown optional keyword
   132                              <1> %endif
   133                              <1> %ifidni _CURRENT_SECTION_TYPE, DATA
   134                              <1>  %assign %%DATASECTION 1
   135                              <1> %else
   136                              <1>  %assign %%DATASECTION 0
   137                              <1> %endif
   138                              <1> %ifidni %4, single
   139                              <1>  %if ELDDATA_NEXT_STATUS == 1		; after next ?
   140                              <1>   %error Unexpected single data link after next data link
   141                              <1>  %elif ELDDATA_NEXT_STATUS == 2		; after last ?
   142                              <1>   %assign ELDDATA_NEXT_STATUS 3		; note single with next/last present
   143                              <1>  %endif
   144                              <1>  %assign %%next 0
   145                              <1> %elifidni %4, next
   146                              <1>  %if ELDDATA_NEXT_STATUS == 0		; no next/last yet ?
   147                              <1>   %assign ELDDATA_NEXT_STATUS 1		; in next
   148                              <1>  %elif ELDDATA_NEXT_STATUS == 2		; after last ?
   149                              <1>   %assign ELDDATA_NEXT_STATUS 1		; in next
   150                              <1>  %elif ELDDATA_NEXT_STATUS == 3		; after single ?
   151                              <1>   %assign ELDDATA_NEXT_STATUS 1		; in next
   152                              <1>  %elif ELDDATA_NEXT_STATUS == 1		; repeated next ?
   153                              <1>   %if ELDDATA_NEXT_ENTRY != %%entry 	|| ELDDATA_NEXT_SECTION != %%DATASECTION 	|| ELDDATA_NEXT_OTHER != ELDOTHERLINK
   156                              <1>    %error Unexpected next data link
   157                              <1>   %endif
   158                              <1>  %else
   159                              <1>   %error Next data link not allowed here
   160                              <1>  %endif
   161                              <1>  %ifn %%optional
   162                              <1>   %error Next data link only valid as optional or PM required
   163                              <1>  %endif
   164                              <1>  %assign %%next 400h
   165                              <1>  %assign ELDDATA_NEXT_ENTRY %%entry
   166                              <1>  %assign ELDDATA_NEXT_SECTION %%DATASECTION
   167                              <1>  %assign ELDDATA_NEXT_OTHER ELDOTHERLINK
   168                              <1> %elifidni %4, last
   169                              <1>  %if ELDDATA_NEXT_STATUS == 0		; no next/last yet ?
   170                              <1>   %error Next last data link not allowed here
   171                              <1>  %elif ELDDATA_NEXT_STATUS == 2		; after last ?
   172                              <1>   %error Next last data link not allowed here
   173                              <1>  %elif ELDDATA_NEXT_STATUS == 3		; after single ?
   174                              <1>   %error Next last data link not allowed here
   175                              <1>  %elif ELDDATA_NEXT_STATUS == 1		; after next ?
   176                              <1>   %if ELDDATA_NEXT_ENTRY != %%entry 	|| ELDDATA_NEXT_SECTION != %%DATASECTION 	|| ELDDATA_NEXT_OTHER != ELDOTHERLINK
   179                              <1>    %error Unexpected next data link
   180                              <1>   %endif
   181                              <1>   %assign ELDDATA_NEXT_STATUS 2		; note now after last
   182                              <1>  %else
   183                              <1>   %error Next data link not allowed here
   184                              <1>  %endif
   185                              <1>  %assign %%next 800h
   186                              <1>  %assign ELDDATA_NEXT_ENTRY -1
   187                              <1>  %assign ELDDATA_NEXT_SECTION -1
   188                              <1> %else
   189                              <1>  %fatal Unknown next keyword
   190                              <1> %endif
   191                              <1> 	%if ELDOTHERLINK
   192                              <1> %if ELDLINKER
   193                              <1>  %xdefine LINK_OTHER_LINKER_DATA_RELOCATIONS LINK_OTHER_LINKER_DATA_RELOCATIONS, 1 + %%DATASECTION + %%optional + %%next, %%entry, %%name
   194                              <1> %else
   195                              <1>  %xdefine LINK_OTHER_DATA_RELOCATIONS LINK_OTHER_DATA_RELOCATIONS, 1 + %%DATASECTION + %%optional + %%next, %%entry, %%name
   196                              <1> %endif
   197                              <1> 	%else
   198                              <1> %if ELDLINKER
   199                              <1>  %xdefine LINK_LINKER_DATA_RELOCATIONS LINK_LINKER_DATA_RELOCATIONS, 1 + %%DATASECTION + %%optional + %%next, %%entry, %%name
   200                              <1> %else
   201                              <1>  %xdefine LINK_DATA_RELOCATIONS LINK_DATA_RELOCATIONS, 1 + %%DATASECTION + %%optional + %%next, %%entry, %%name
   202                              <1> %endif
   203                              <1> 	%endif
   204                              <1> %defstr %%string %1
   205                              <1> %strlen %%length %%string
   206                              <1> %if %%length > 64
   207                              <1> 	; Could be increased, but mustn't exceed 127 bytes
   208                              <1> 	;  because flag 80h is used to mark optional links
   209                              <1> 	;  that failed to be matched.
   210                              <1>  %error Too long link name: %1
   211                              <1> %endif
   212                              <1> %define LINK_DATA_CHECK %1
   213                              <1> 	%if ELDOTHERLINK
   214                              <1> 	linkdata_detect LINK_OTHER_DATA_DETECTION
   215                              <1> %if LINK_DATA_NEW
   216                              <1>  %xdefine LINK_OTHER_DATA_DETECTION LINK_OTHER_DATA_DETECTION, %1, %%name
   217                              <1> 	hashdef HASH, %%string
   218                              <1>  %xdefine LINK_OTHER_DATA_NAMES 	LINK_OTHER_DATA_NAMES, %%name:, dw _HASH, {counted %%string}
   220                              <1> %else
   221                              <1>  %%name equ LINK_DATA_DUPLICATE
   222                              <1> %endif
   223                              <1> 	%else
   224                              <1> 	linkdata_detect LINK_DATA_DETECTION
   225                              <1> %if LINK_DATA_NEW
   226                              <1>  %xdefine LINK_DATA_DETECTION LINK_DATA_DETECTION, %1, %%name
   227                              <1> 	hashdef HASH, %%string
   228                              <1>  %xdefine LINK_DATA_NAMES 	LINK_DATA_NAMES, %%name:, dw _HASH, {counted %%string}
   230                              <1> %else
   231                              <1>  %%name equ LINK_DATA_DUPLICATE
   232                              <1> %endif
   233                              <1> 	%endif
   234                              <1> 	eldstrictcheck
   235                              <1> 	%endmacro
   236                              <1> 
   237                              <1> 	%imacro linkdata_detect 2-*.nolist
   238                              <1> %assign LINK_DATA_NEW 1
   239                              <1> %rep (%0 - 2) / 2
   240                              <1>  %rotate 2
   241                              <1>  %ifidni %1, LINK_DATA_CHECK
   242                              <1>   %assign LINK_DATA_NEW 0
   243                              <1>   %xdefine LINK_DATA_DUPLICATE %2
   244                              <1>   %exitrep
   245                              <1>  %endif
   246                              <1> %endrep
   247                              <1> 	%endmacro
   248                              <1> 
   249                              <1> 	%imacro link_data_dump_names 1-*.nolist
   250                              <1> %rep %0
   251                              <1> 	%1
   252                              <1>  %rotate 1
   253                              <1> %endrep
   254                              <1> 	%endmacro
   255                              <1> 
   256                              <1> ; dw LINK_LINKER_DATA_RELOCATIONS, 0, 0
   257                              <1> ; dw LINK_DATA_RELOCATIONS, 0, 0
   258                              <1> ; link_data_dump_names ELDCALL_CODE_NAMES
   259                              <1> 
   260                              <1> %endif
    11                                  
    12                                  	cpu 8086
    13                                  
    14                                  	addsection RELOCATEDDATA, nobits vstart=_ELD_RELOC_VSTART
    15                                  relocateddata:
    16                                  
    17                                  	addsection HEADER, start=0
    18                                  
    19                                  	istruc ELD_HEADERX
    20                                  at eldhxHeader
    21                                  		; ELD executable header
    22                                  	istruc ELD_HEADER
    23 00000000 454C4431                at eldhSignature,	db "ELD1"
    24 00000004 000000                  			db 0,0,0
    25 00000007 1A                      			db 26
    26 00000008 60000000                at eldhCodeOffset,	dd CODEOFFSET
    27 0000000C C009                    at eldhCodeImageLength,	dw code_size
    28 0000000E 0000                    at eldhCodeAllocLength,	dw 0
    29 00000010 200A0000                at eldhDataOffset,	dd DATAOFFSET
    30 00000014 D001                    at eldhDataImageLength,	dw data_size
    31 00000016 2000                    at eldhDataAllocLength,	dw total_data_size - data_size
    32 00000018 D402                    at eldhCodeEntrypoint,	dw linker - code
    33                                  at eldhReserved
    34 0000001A 00<rep 4h>2800          at eldhExtensionSize,	dw header_extension_end - $$
    35                                  	iend
    36 00000020 [30000000]              at eldhxDescriptionOffset,	dd description
    37 00000024 A30A0000                at eldhxHelpOffset,		dd DATAOFFSET + msg.help - datastart
    38                                  PUT_ELDHX_DATETIME_OFFSET
    39                                  header_extension_end:
    40 00000028 00<rep 8h>              	iend
    41                                  
    42 00000030 446973706C6179206D-     description:		asciz "Display messages received on AMIS function 40h."
    42 00000039 657373616765732072-
    42 00000042 65636569766564206F-
    42 0000004B 6E20414D4953206675-
    42 00000054 6E6374696F6E203430-
    42 0000005D 682E00             
    43                                  
    44                                  
    45                                  	align 16, db 0
    46                                  
    47                                  CODEOFFSET equ $ - $$
    48                                  	addsection CODE, follows=HEADER vstart=_ELD_CODE_VSTART
    49                                  %define CODEFIXUP - code + 0
    50                                  code:
    51                                  code_start:
    52                                  		; ELD instance header
    53                                  	istruc ELD_INSTANCE
    54                                  at eldiStartCode
    55 00000000 00<rep 2h>              at eldiEndCode
    56 00000002 00<rep 2h>              at eldiStartData
    57 00000004 00<rep 2h>              at eldiEndData
    58 00000006 00<rep 2h>414D4953-     at eldiIdentifier,	fill 8, 32, db "AMISMSG"
    58 0000000C 4D534720           
    59 00000010 00<rep 2h>616D6973-     at eldiListing,		asciz _ELD_LISTING
    59 00000016 6D73672E6C737400   
    60 0000001E 00<rep 2h>              	iend
    61                                  
    62                                  
    63                                  DATAOFFSET equ CODEOFFSET + code_size
    64                                  	addsection DATA, follows=CODE vstart=_ELD_DATA_VSTART
    65                                  %define DATAFIXUP - datastart + 0
    66                                  datastart:
    67                                  PUT_ELD_DATETIME
    68                                  
    69                                  
    70                                  	usesection CODE
    71                                  
    72                                  command:
    73 00000020 EB08                    	jmp strict short .entry
    74                                  .chain:
    75 00000022 E8[0000]EB020000        	extcall cmd3_not_ext, required	; must NOT be extcallcall
    76 00000029 90                      	times 10 - ($ - command) nop
    77                                  .entry:
    78 0000002A 56                      	push si
    79 0000002B 3C2D                    	cmp al, '-'
    80 0000002D 7503                    	jne @F
    81 0000002F E8B601                  	extcallcall skipcomma
    82                                  @@:
    83 00000032 4E                      	dec si
    84                                  
    85 00000033 BA[0100]                	mov dx, msg.amismsg
    86                                  internaldatarelocation
    87 00000036 E8B701                  	extcallcall isstring?
    88 00000039 7405                    	je @F
    89                                  .transfer_to_chain:
    90 0000003B 5E                      	pop si
    91 0000003C 4E                      	dec si
    92 0000003D AC                      	lodsb
    93 0000003E EBE2                    	jmp .chain
    94                                  
    95                                  @@:
    96 00000040 E8A501                  	extcallcall skipcomma
    97 00000043 4E                      	dec si
    98 00000044 C706[0000][0000]        reloc2	mov word [relocateddata], relocateddata
    99                                  linkdatarelocation lastcmd, -4
   100                                  linkdatarelocation dmycmd
   101 0000004A BA[0000]                	mov dx, relocateddata
   102                                  linkdatarelocation msg.uninstall
   103 0000004D E8A001                  	extcallcall isstring?
   104 00000050 7503E9A400              	je uninstall
   105 00000055 BA[0900]                	mov dx, msg.display
   106                                  internaldatarelocation
   107 00000058 E89501                  	extcallcall isstring?
   108 0000005B AC                      	lodsb
   109 0000005C 7406                    	je display
   110 0000005E E89701                  	extcallcall chkeol
   111                                  @@:
   112 00000061 E89C01                  	extcallcall cmd3
   113                                  
   114                                  display:
   115 00000064 E89101                  	extcallcall chkeol
   116 00000067 E86C00                  	call display_internal
   117 0000006A EBF5                    	jmp @B
   118                                  
   119                                  
   120                                  amis:
   121 0000006C EB03                    	jmp strict short .entry
   122                                  .chain:
   123 0000006E CB                      	retf
   124 0000006F 90<rep 2h>              	times 5 - ($ - amis) nop
   125                                  .entry:
   126                                  	lframe far
   127                                  	lpar word, intfl
   128                                  	lpar word, intcs
   129                                  	lpar word, intip
   130                                  	lpar word, ax
   131                                  	lpar word, bx
   132                                  	lpar word, cx
   133                                  	lpar word, dx
   134                                  	lpar word, ds
   135                                  	lpar_return
   136 00000071 5589E5                  	lenter
   137 00000074 06                      	push es
   138 00000075 56                      	push si
   139 00000076 57                      	push di
   140 00000077 1E                      	push ds
   141 00000078 3C41                    	cmp al, 41h
   142 0000007A 750E                    	jne .notquery
   143                                  
   144 0000007C B001                    	mov al, 1
   145 0000007E D006[E501]              	rol byte [messagewritten], 1
   146                                  internaldatarelocation
   147 00000082 7201                    	jc @F
   148 00000084 40                      	inc ax
   149                                  @@:
   150 00000085 88460E                  	mov byte [bp + ?ax], al
   151 00000088 EB43                    	jmp .return
   152                                  
   153                                  .notquery:
   154 0000008A 3C40                    	cmp al, 40h
   155 0000008C 753E                    	jne .transfer
   156 0000008E 1E                      	push ds
   157 0000008F 07                      	pop es
   158 00000090 8EDA                    	mov ds, dx
   159 00000092 89DE                    	mov si, bx
   160 00000094 BF[6400]                	mov di, message
   161                                  internaldatarelocation
   162 00000097 B9C000                  	mov cx, words(message.size)
   163 0000009A F3A5                    	rep movsw			; copy data
   164 0000009C C6460EFF                	mov byte [bp + ?ax], 0FFh	; default: return al = 0FFh
   165 000000A0 B000                    	mov al, 0			; NUL
   166 000000A2 BF[6400]                	mov di, message			; es:di -> written message
   167                                  internaldatarelocation
   168 000000A5 B98001                  	mov cx, message.size		; cx = size of buffer
   169 000000A8 F2AE                    	repne scasb			; scan for NUL
   170 000000AA 7403                    	je @F				; found -->
   171                                  		; byte [message.overflow] = NUL, so no need to terminate
   172 000000AC FE4E0E                  	dec byte [bp + ?ax]		; return al = 0FEh
   173                                  @@:
   174 000000AF 1F                      	 pop ds
   175 000000B0 1E                      	 push ds
   176 000000B1 D006[0000]              	rol byte [injecting], 1
   177                                  internaldatarelocation
   178 000000B5 720E                    	jc @F
   179 000000B7 F616[0000]              	not byte [injecting]
   180                                  internaldatarelocation
   181 000000BB B8[E200]                	mov ax, inject
   182                                  internalcoderelocation
   183 000000BE 8706[0000]              	xchg ax, word [relocateddata]
   184                                  linkdatarelocation ext_inject_handler
   185 000000C2 A3[6200]                	mov word [old_inject], ax
   186                                  internaldatarelocation
   187                                  @@:
   188 000000C5 C606[E501]00            	mov byte [messagewritten], 0
   189                                  internaldatarelocation -3
   190 000000CA EB01                    	jmp .return
   191                                  
   192                                  .transfer:
   193 000000CC A8                      	db __TEST_IMM8		; (NC)
   194                                  .return:
   195 000000CD F9                      	stc
   196 000000CE 1F                      	pop ds
   197 000000CF 5F                      	pop di
   198 000000D0 5E                      	pop si
   199 000000D1 07                      	pop es
   200 000000D2 5D                      	lleave , optimiserestoresp
   201 000000D3 7399                    	jnc .chain
   202 000000D5 CB                      	retf
   203                                  
   204                                  
   205                                  display_internal:
   206 000000D6 BA[6400]                	mov dx, message
   207                                  internaldatarelocation
   208 000000D9 E82C01                  	extcallcall putsz
   209 000000DC C606[E501]FF            	mov byte [messagewritten], -1
   210                                  internaldatarelocation -3
   211 000000E1 C3                      	retn
   212                                  
   213                                  
   214                                  inject:
   215 000000E2 E8F1FF                  	call display_internal
   216 000000E5 C606[0000]00            	mov byte [injecting], 0
   217                                  internaldatarelocation -3
   218 000000EA 8B0E[6200]              	mov cx, word [old_inject]
   219                                  internaldatarelocation
   220 000000EE E302                    	jcxz .notinject
   221 000000F0 FFE1                    	jmp cx
   222                                  
   223                                  .notinject:
   224 000000F2 E8[0000]EB020000        	extcall cmd3_not_inject
   225                                  
   226                                  
   227                                  uninstall:
   228 000000F9 AC                      	lodsb
   229 000000FA E8FB00                  	extcallcall chkeol
   230                                  
   231 000000FD 8E06[0000]              	mov es, word [relocateddata]
   232                                  linkdatarelocation extdssel
   233 00000101 E80C01                  	extcallcall ispm
   234 00000104 7404                    	jz @F
   235 00000106 8E06[0000]              	mov es, word [relocateddata]
   236                                  linkdatarelocation extseg
   237                                  @@:
   238 0000010A 06                      	push es
   239 0000010B 1F                      	pop ds
   240                                  
   241 0000010C 36D006[0000]            	rol byte [ss:injecting], 1
   242                                  internaldatarelocation
   243 00000111 7303E9BB00              	jc uninstall_command.error
   244                                  
   245                                  uninstall_amis:
   246 00000116 31DB                    	xor bx, bx		; = 0 (no prior, modify ext_command_handler)
   247 00000118 BF[6C00]                	mov di, amis		; di -> us
   248                                  internalcoderelocation
   249 0000011B 813D9090                	cmp word [di], 9090h
   250 0000011F 7452                    	je .amis_done
   251 00000121 368B36[0000]            	mov si, word [ss:relocateddata]
   252                                  linkdatarelocation ext_amis_handler
   253                                  				; si -> first
   254 00000126 85F6                    	test si, si		; none installed ?
   255 00000128 7503E9A400              	jz .error		; error -->
   256                                  
   257                                  .loop:
   258 0000012D 39F7                    	cmp di, si		; found ?
   259 0000012F 7410                    	je .bx			; yes, use bx -->
   260 00000131 89F3                    	mov bx, si		; bx -> prior handler
   261 00000133 AD                      	lodsw			; skip entrypoint jmp strict short
   262 00000134 AC                      	lodsb			; get first byte of chainer
   263 00000135 3CE9                    	cmp al, 0E9h		; expecting jmp near ?
   264 00000137 7403E99500              	jne .error		; no, error -->
   265 0000013C AD                      	lodsw			; get rel16 displacement
   266 0000013D 01C6                    	add si, ax		; -> next handler
   267 0000013F EBEC                    	jmp .loop
   268                                  
   269                                  .bx:
   270 00000141 85DB                    	test bx, bx		; any prior ?
   271 00000143 751A                    	jnz .bxnz		; yes -->
   272 00000145 AF                      	scasw			; skip entrypoint jmp strict short
   273 00000146 803DCB                  	cmp byte [di], 0CBh	; is it a retf ?
   274 00000149 7507                    	jne @F			; no -->
   275                                  				; yes, reset ext_amis_handler to zero
   276                                  .setbx:
   277 0000014B 36891E[0000]            	mov word [ss:relocateddata], bx
   278                                  linkdatarelocation ext_amis_handler
   279 00000150 EB1B                    	jmp .done
   280                                  
   281                                  @@:
   282 00000152 803DE9                  	cmp byte [di], 0E9h	; validate
   283 00000155 757A                    	jne .error		; failure -->
   284 00000157 47                      	inc di			; -> rel16 displacement
   285 00000158 8B1D                    	mov bx, word [di]	; get displacement
   286 0000015A AF                      	scasw			; -> after jmp near
   287 0000015B 01FB                    	add bx, di		; -> next handler
   288 0000015D EBEC                    	jmp .setbx		; set ext_amis_handler to next
   289                                  
   290                                  .bxnz:
   291 0000015F 89DE                    	mov si, bx		; -> prior handler with us as downlink
   292 00000161 87FE                    	xchg di, si		; si -> ours, di -> prior
   293 00000163 A7                      	cmpsw			; skip entrypoint jmp strict short
   294 00000164 A4                      	movsb			; copy 0CBh/0E9h
   295 00000165 AD                      	lodsw			; ax = near rel16 displacement (if 0E9h)
   296 00000166 01F0                    	add ax, si		; add in our base (= absolute offset)
   297 00000168 29F8                    	sub ax, di
   298 0000016A 48                      	dec ax
   299 0000016B 48                      	dec ax			; subtract new base (= relative displacement)
   300 0000016C AB                      	stosw			; store new rel16 displacement
   301                                  .done:
   302 0000016D C706[6C00]9090          	mov word [amis], 9090h
   303                                  internalcoderelocation -4
   304                                  .amis_done:
   305                                  
   306                                  .error equ uninstall_command.error
   307                                  
   308                                  uninstall_command:
   309 00000173 31DB                    	xor bx, bx		; = 0 (no prior, modify ext_command_handler)
   310 00000175 BF[2000]                	mov di, command		; di -> us
   311                                  internalcoderelocation
   312 00000178 368B36[0000]            	mov si, word [ss:relocateddata]
   313                                  linkdatarelocation ext_command_handler
   314                                  				; si -> first
   315 0000017D 85F6                    	test si, si		; none installed ?
   316 0000017F 7450                    	jz .error		; error -->
   317                                  
   318                                  .loop:
   319 00000181 39F7                    	cmp di, si		; found ?
   320 00000183 740D                    	je .bx			; yes, use bx -->
   321 00000185 89F3                    	mov bx, si		; bx -> prior handler
   322 00000187 AD                      	lodsw			; skip entrypoint jmp strict short
   323 00000188 AC                      	lodsb			; get first byte of chainer
   324 00000189 3CE9                    	cmp al, 0E9h		; expecting jmp near ?
   325 0000018B 7544                    	jne .error		; no, error -->
   326 0000018D AD                      	lodsw			; get rel16 displacement
   327 0000018E 01C6                    	add si, ax		; -> next handler
   328 00000190 EBEF                    	jmp .loop
   329                                  
   330                                  .bx:
   331 00000192 85DB                    	test bx, bx		; any prior ?
   332 00000194 751A                    	jnz .bxnz		; yes -->
   333 00000196 AF                      	scasw			; skip entrypoint jmp strict short
   334 00000197 803DE8                  	cmp byte [di], 0E8h	; is it a call to cmd3_not_ext ?
   335 0000019A 7507                    	jne @F			; no -->
   336                                  				; yes, reset ext_command_handler to zero
   337                                  .setbx:
   338 0000019C 36891E[0000]            	mov word [ss:relocateddata], bx
   339                                  linkdatarelocation ext_command_handler
   340 000001A1 EB1E                    	jmp .done
   341                                  
   342                                  @@:
   343 000001A3 803DE9                  	cmp byte [di], 0E9h	; validate
   344 000001A6 7529                    	jne .error		; failure -->
   345 000001A8 47                      	inc di			; -> rel16 displacement
   346 000001A9 8B1D                    	mov bx, word [di]	; get displacement
   347 000001AB AF                      	scasw			; -> after jmp near
   348 000001AC 01FB                    	add bx, di		; -> next handler
   349 000001AE EBEC                    	jmp .setbx		; set ext_command_handler to next
   350                                  
   351                                  .bxnz:
   352 000001B0 89DE                    	mov si, bx		; -> prior handler with us as downlink
   353 000001B2 87FE                    	xchg di, si		; si -> ours, di -> prior
   354 000001B4 A7                      	cmpsw			; skip entrypoint jmp strict short
   355 000001B5 A4                      	movsb			; copy 0E8h/0E9h
   356 000001B6 AD                      	lodsw			; ax = near rel16 displacement
   357 000001B7 01F0                    	add ax, si		; add in our base (= absolute offset)
   358 000001B9 29F8                    	sub ax, di
   359 000001BB 48                      	dec ax
   360 000001BC 48                      	dec ax			; subtract new base (= relative displacement)
   361 000001BD AB                      	stosw			; store new rel16 displacement
   362 000001BE A5                      	movsw			; jmp strict short
   363 000001BF A5                      	movsw			; linkcall target
   364 000001C0 A4                      	movsb			; trailer
   365                                  .done:
   366 000001C1 8026[1000]FE            	clropt [code + eldiFlags], eldifResident
   367                                  internalcoderelocation -3	; mark block as free
   368 000001C6 BA[1100]                	mov dx, msg.uninstall_done
   369                                  internaldatarelocation
   370                                  @@:
   371 000001C9 16                      	push ss
   372 000001CA 1F                      	pop ds
   373 000001CB E83A00                  	extcallcall putsz
   374 000001CE E82F00                  	extcallcall cmd3	; return
   375                                  
   376                                  .error:
   377 000001D1 B8010E                  	mov ax, 0E01h
   378 000001D4 E84100                  	extcallcall setrc
   379 000001D7 BA[3500]                	mov dx, msg.uninstall_error
   380                                  internaldatarelocation
   381 000001DA EBED                    	jmp @B
   382                                  
   383                                  
   384                                  error:
   385 000001DC E8[0000]EB020000        	extcall error
   386                                  
   387 000001E3 90<rep 5h>E8[0000]-     	eldcall_dump_callcall ELDCALL_CALLCALL_LIST
   387 000001EB EB020000C3E8[0000]-
   387 000001F3 EB020000C3E8[0000]-
   387 000001FB EB020000C3E8[0000]-
   387 00000203 EB020000C3E8[0000]-
   387 0000020B EB020000C3E8[0000]-
   387 00000213 EB020000C3E8[0000]-
   387 0000021B EB020000C3         
   388                                  
   389                                  endinstalled equ ($ + CODEFIXUP + 15) & ~15
   390                                  
   391                                  
   392                                  start:
   393 00000220 8CC3                    	mov bx, es
   394 00000222 16                      	 push ss
   395 00000223 07                      	 pop es
   396 00000224 E8C1FF                  	call skipcomma
   397 00000227 4E                      	dec si
   398 00000228 BA[0000]                	mov dx, relocateddata
   399                                  linkdatarelocation msg.install
   400 0000022B E8C2FF                  	call isstring?
   401 0000022E 7433                    	je install
   402                                  
   403 00000230 BA[8300]                	mov dx, msg.help
   404                                  internaldatarelocation
   405 00000233 E8[0000]EB020000        	extcall putsz
   406                                  @@:
   407 0000023A E80300                  	call uninstall_oneshot
   408 0000023D 31C0                    	xor ax, ax
   409 0000023F CB                      	retf
   410                                  
   411                                  
   412                                  uninstall_oneshot:
   413 00000240 36F606[0000]01          	testopt [ss:relocateddata], 1
   414                                  linkdatarelocation options7, -3
   415 00000246 751A                    	jnz @F
   416                                  
   417 00000248 2EA1[0200]              	mov ax, word [cs:code + eldiEndCode]
   418                                  internalcoderelocation
   419 0000024C 2E2B06[0000]            	sub ax, word [cs:code + eldiStartCode]
   420                                  internalcoderelocation
   421 00000251 2906[0000]              	sub word [relocateddata], ax
   422                                  linkdatarelocation extseg_used
   423                                  
   424 00000255 2EA1[0600]              	mov ax, word [cs:code + eldiEndData]
   425                                  internalcoderelocation
   426 00000259 2E2B06[0400]            	sub ax, word [cs:code + eldiStartData]
   427                                  internalcoderelocation
   428 0000025E 2906[0000]              	sub word [relocateddata], ax
   429                                  linkdatarelocation extdata_used
   430                                  @@:
   431 00000262 C3                      	retn
   432                                  
   433                                  
   434                                  	usesection DATA
   435                                  	align 2, db 0
   436                                  
   437 00000000 00                      injecting:	db 0
   438                                  
   439                                  
   440                                  msg:
   441 00000001 414D49534D534700        .amismsg:		asciz "AMISMSG"
   442 00000009 444953504C415900        .display:		asciz "DISPLAY"
   443 00000011 414D4953206D657373-     .uninstall_done:	db "AMIS message display uninstalled."
   443 0000001A 61676520646973706C-
   443 00000023 617920756E696E7374-
   443 0000002C 616C6C65642E       
   444                                  %if _ELD_RECLAIM_HINT
   445                                  			db " (Don't forget to use reclaim.eld)"
   446                                  %endif
   447 00000032 0D0A00                  			asciz 13,10
   448 00000035 414D4953206D657373-     .uninstall_error:	asciz "AMIS message display unable to uninstall!",13,10
   448 0000003E 61676520646973706C-
   448 00000047 617920756E61626C65-
   448 00000050 20746F20756E696E73-
   448 00000059 74616C6C210D0A00   
   449                                  
   450                                  uinit_data: equ $
   451                                  
   452 00000061 414D4953206D657373-     .installed:	asciz "AMIS message display installed.",13,10
   452 0000006A 61676520646973706C-
   452 00000073 617920696E7374616C-
   452 0000007C 6C65642E0D0A00     
   453 00000083 496E7374616C6C2074-     .help:		db "Install this ELD using an INSTALL keyword.",13,10
   453 0000008C 68697320454C442075-
   453 00000095 73696E6720616E2049-
   453 0000009E 4E5354414C4C206B65-
   453 000000A7 79776F72642E0D0A   
   454 000000AF 0D0A                    		db 13,10
   455 000000B1 446973706C61797320-     		db "Displays up to 384 Byte ASCIZ string sent to AMIS function 40h.",13,10
   455 000000BA 757020746F20333834-
   455 000000C3 204279746520415343-
   455 000000CC 495A20737472696E67-
   455 000000D5 2073656E7420746F20-
   455 000000DE 414D49532066756E63-
   455 000000E7 74696F6E203430682E-
   455 000000F0 0D0A               
   456 000000F2 43616C6C2061732041-     		db "Call as AH = multiplex number, AL = 40h, DX:BX -> message.",13,10
   456 000000FB 48203D206D756C7469-
   456 00000104 706C6578206E756D62-
   456 0000010D 65722C20414C203D20-
   456 00000116 3430682C2044583A42-
   456 0000011F 58202D3E206D657373-
   456 00000128 6167652E0D0A       
   457 0000012E 446973706C6179206F-     		db "Display occurs before reading the next command in cmd3.",13,10
   457 00000137 636375727320626566-
   457 00000140 6F7265207265616469-
   457 00000149 6E6720746865206E65-
   457 00000152 787420636F6D6D616E-
   457 0000015B 6420696E20636D6433-
   457 00000164 2E0D0A             
   458 00000167 0D0A                    		db 13,10
   459 00000169 52756E207769746820-     		db "Run with AMISMSG DISPLAY to re-display last message.",13,10
   459 00000172 414D49534D53472044-
   459 0000017B 4953504C415920746F-
   459 00000184 2072652D646973706C-
   459 0000018D 6179206C617374206D-
   459 00000196 6573736167652E0D0A 
   460 0000019F 52756E207769746820-     		db "Run with AMISMSG UNINSTALL to uninstall.",13,10
   460 000001A8 414D49534D53472055-
   460 000001B1 4E494E5354414C4C20-
   460 000001BA 746F20756E696E7374-
   460 000001C3 616C6C2E0D0A       
   461 000001C9 00                      		asciz
   462                                  
   463                                  
   464 000001CA 00<rep 6h>              	align 16, db 0
   465                                  init_data_end:
   466                                  data_size equ $ - datastart
   467                                  transient_data_size equ data_size
   468                                  
   469                                  	absolute uinit_data
   470                                  
   471 00000061 ??                      	alignb 2
   472 00000062 ????                    old_inject:	resw 1
   473                                  message:
   474 00000064 <res 180h>              .:		resb 384
   475                                  .size equ $ - .
   476 000001E4 ??                      .overflow:	resb 1
   477 000001E5 ??                      messagewritten:	resb 1
   478                                  
   479 000001E6 <res Ah>                	alignb 16
   480                                  uinit_data_end:
   481                                  resident_data_end:
   482                                  resident_data_size equ resident_data_end - datastart
   483                                  
   484                                  %if uinit_data_end >= init_data_end
   485                                   total_data_size equ $ - datastart
   486                                  %else
   487                                   total_data_size equ init_data_end - datastart
   488                                  %endif
   489                                  %assign _DATA_SIZE total_data_size
   490                                  
   491                                  
   492                                  	usesection CODE
   493                                  
   494                                  install:
   495 00000263 AC                      	lodsb
   496 00000264 E8[0000]EB020000        	extcall chkeol
   497                                  
   498                                  	houdini
   499 0000026B 8EC3                    	mov es, bx		; => ext seg (writable)
   500                                  
   501 0000026D B8C000                  	mov ax, endresident - endinstalled
   502 00000270 262906[0200]            	sub word [es:code + eldiEndCode], ax
   503                                  internalcoderelocation		; adjust size
   504 00000275 2906[0000]              	sub word [relocateddata], ax
   505                                  linkdatarelocation extseg_used	; adjust size
   506                                  
   507                                  %if (transient_data_size - resident_data_size) > 0
   508                                  	mov ax, transient_data_size - resident_data_size
   509                                  	sub word [es:code + eldiEndData], ax
   510                                  internalcoderelocation		; adjust size
   511                                  	sub word [relocateddata], ax
   512                                  linkdatarelocation extdata_used	; adjust size
   513                                  %endif
   514                                  
   515 00000279 8B1E[0000]              	mov bx, word [relocateddata]
   516                                  linkdatarelocation ext_command_handler
   517                                  				; -> prior
   518 0000027D BF[2000]                	mov di, command		; -> our handler
   519                                  internalcoderelocation
   520 00000280 85DB                    	test bx, bx		; installing as first ?
   521 00000282 740A                    	jz .only_first		; yes, simple --> (leave as extcall cmd3_not_ext)
   522 00000284 AF                      	scasw			; skip entrypoint jmp strict short
   523 00000285 B0E9                    	mov al, 0E9h		; = jmp near opcode
   524 00000287 AA                      	stosb			; store
   525 00000288 93                      	xchg ax, bx		; ax -> next handler
   526 00000289 29F8                    	sub ax, di
   527 0000028B 48                      	dec ax
   528 0000028C 48                      	dec ax			; ax = ax - (di + 2)
   529 0000028D AB                      	stosw			; store our downlink as rel16 displacement
   530                                  
   531                                  .only_first:
   532 0000028E 26800E[1000]01          	setopt [es:code + eldiFlags], eldifResident
   533                                  internalcoderelocation -3	; mark block as resident
   534 00000294 C706[0000][2000]        	mov word [relocateddata], command
   535                                  linkdatarelocation ext_command_handler, -4
   536                                  internalcoderelocation		; -> our entrypoint
   537                                  
   538                                  
   539 0000029A 8B1E[0000]              	mov bx, word [relocateddata]
   540                                  linkdatarelocation ext_amis_handler
   541                                  				; -> prior
   542 0000029E BF[6C00]                	mov di, amis		; -> our handler
   543                                  internalcoderelocation
   544 000002A1 85DB                    	test bx, bx		; installing as first ?
   545 000002A3 740A                    	jz .amis_only_first	; yes, simple --> (leave as extcall cmd3_not_ext)
   546 000002A5 AF                      	scasw			; skip entrypoint jmp strict short
   547 000002A6 B0E9                    	mov al, 0E9h		; = jmp near opcode
   548 000002A8 AA                      	stosb			; store
   549 000002A9 93                      	xchg ax, bx		; ax -> next handler
   550 000002AA 29F8                    	sub ax, di
   551 000002AC 48                      	dec ax
   552 000002AD 48                      	dec ax			; ax = ax - (di + 2)
   553 000002AE AB                      	stosw			; store our downlink as rel16 displacement
   554                                  
   555                                  .amis_only_first:
   556 000002AF C706[0000][6C00]        	mov word [relocateddata], amis
   557                                  linkdatarelocation ext_amis_handler, -4
   558                                  internalcoderelocation		; -> our entrypoint
   559                                  
   560                                  
   561 000002B5 F606[0000]04            	testopt [relocateddata], 4
   562                                  linkdatarelocation options7, -3
   563 000002BA 7506                    	jnz @F
   564 000002BC BA[6100]                	mov dx, msg.installed
   565                                  internaldatarelocation
   566 000002BF E846FF                  	call putsz
   567                                  @@:
   568                                  
   569 000002C2 C606[6400]00            	mov byte [message], 0
   570                                  internaldatarelocation -3
   571 000002C7 C606[E401]00            	mov byte [message.overflow], 0
   572                                  internaldatarelocation -3
   573 000002CC C606[E501]FF            	mov byte [messagewritten], -1
   574                                  internaldatarelocation -3
   575                                  
   576 000002D1 31C0                    	xor ax, ax
   577 000002D3 CB                      	retf
   578                                  
   579                                  
   580                                  %include "eldlink.asm"
     1                              <1> %if 0
     2                              <1> 
     3                              <1> Extensions for lDebug linker
     4                              <1> 
     5                              <1> Copyright (C) 2008-2025 E. C. Masloch
     6                              <1> 
     7                              <1> Usage of the works is permitted provided that this
     8                              <1> instrument is retained with the works, so that any entity
     9                              <1> that uses the works is notified of this instrument.
    10                              <1> 
    11                              <1> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <1> 
    13                              <1> %endif
    14                              <1> 
    15                              <1> %include "lmacros3.mac"
     1                              <2> [list -]
    16                              <1> %include "eld.mac"
     1                              <2> %if 0
     2                              <2> 
     3                              <2> Extensions for lDebug macros
     4                              <2> 
     5                              <2> Copyright (C) 2008-2025 E. C. Masloch
     6                              <2> 
     7                              <2> Usage of the works is permitted provided that this
     8                              <2> instrument is retained with the works, so that any entity
     9                              <2> that uses the works is notified of this instrument.
    10                              <2> 
    11                              <2> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                              <2> 
    13                              <2> %endif
    14                              <2> 
    15                              <2> %ifndef ELD_MAC
    16                              <2> %define ELD_MAC 1
    17                              <2> 
    18                              <2> %include "lmacros3.mac"
    19                              <2> 
    20                              <2> 		; ELD executable header
    21                              <2> 	struc ELD_HEADER
    22                              <2> eldhSignature:		resb 4	; "ELD1"
    23                              <2> 			resb 3	; reserved
    24                              <2> 			resb 1	; 26 (Ctrl-Z)
    25                              <2> eldhCodeOffset:		resd 1	; position displacement from eldhSignature
    26                              <2> eldhCodeImageLength:	resw 1	; amount bytes, at least 32
    27                              <2> eldhCodeAllocLength:	resw 1	; amount bytes, added to prior. sum < 64 KiB
    28                              <2> eldhDataOffset:		resd 1
    29                              <2> eldhDataImageLength:	resw 1	; (zero allowed)
    30                              <2> eldhDataAllocLength:	resw 1	; (zero allowed)
    31                              <2> eldhCodeEntrypoint:	resw 1	; within code section, used as displacement
    32                              <2> eldhReserved:		resb 4	; reserved
    33                              <2> eldhExtensionSize:	resw 1	; from eldhSignature, -> past eldhx fields in use
    34                              <2> 	endstruc
    35                              <2> 	endarea ELD_HEADER, 1
    36                              <2> 
    37                              <2> 	struc ELD_HEADERX
    38                              <2> eldhxHeader:		resb ELD_HEADER_size
    39                              <2> eldhxDescriptionOffset:	resd 1	; zero if none, from eldhxHeader. <= 128 Bytes
    40                              <2> eldhxHelpOffset:	resd 1	; zero if none, from eldhxHeader
    41                              <2> eldhxLibTable:		resd 1	; zero if none, from eldhxHeader
    42                              <2> eldhxDateTimeOffset:	resd 1	; zero if none, from eldhxHeader
    43                              <2> 	alignb 16
    44                              <2> 	endstruc
    45                              <2> 
    46                              <2> 	struc ELD_TRAILER_HEADER
    47                              <2> eldthSignature:		resb 8	; "ELD1TAIL"
    48                              <2> eldthHeaderOffset:	resd 1	; negative displacement from eldthSignature,
    49                              <2> 				;  add this dword to the seek offset
    50                              <2> eldthReserved:		resw 1	; reserved, must be initialised to zero
    51                              <2> eldthChecksum:		resw 1	; sum of all words in trailer header = 0
    52                              <2> 	endstruc
    53                              <2> 	endarea ELD_TRAILER_HEADER, 1
    54                              <2> 
    55                              <2> 	struc ELD_LIBTABLE
    56                              <2> eldltFormat:		resw 1
    57                              <2> 	; 0 = uncompressed
    58                              <2> 	; 2 = heatshrink compressed
    59                              <2> 	; 3 = lzexedat -4 compressed
    60                              <2> 	; 4 = lzexedat -4 -l compressed
    61                              <2> eldltAmount:		resw 1
    62                              <2> eldltOffset:		resd 1	; from eldhxHeader
    63                              <2> eldltCompressedLength:		; (dword, only present if format 2, 3, or 4)
    64                              <2> 	endstruc
    65                              <2> 	endarea ELD_LIBTABLE, 1
    66                              <2> 
    67                              <2> 		; ELD instance header
    68                              <2> 	struc ELD_INSTANCE
    69                              <2> eldiStartCode:		resw 1	; -> this structure itself (para aligned)
    70                              <2> eldiEndCode:		resw 1	; -> behind memory used by instance (para aligned)
    71                              <2> eldiStartData:		resw 1	; -> data in data entry section (para aligned), or 0
    72                              <2> eldiEndData:		resw 1	; -> behind data (para aligned), or 0
    73                              <2> eldiIdentifier:		resb 8	; blank-filled text
    74                              <2> eldiFlags:		resw 1	; flags
    75                              <2> eldiListing_size equ 14
    76                              <2> eldiListing:		resb eldiListing_size
    77                              <2> 				; ASCIZ listing file name
    78                              <2> 	endstruc
    79                              <2> 		; flags for eldiFlags:
    80                              <2> eldifResident:		equ 1
    81                              <2> 
    82                              <2> 		; ELD link info header
    83                              <2> 	struc ELD_LINKINFO
    84                              <2> eldlSignature:		resw 1	; 0E1D1h
    85                              <2> eldlReserved:		resw 2
    86                              <2> eldlUseLinkHash:	resw 1
    87                              <2> eldlDataAmount:		resw 1
    88                              <2> eldlDataPrefixes:	resw 1
    89                              <2> eldlDataEntries:	resw 1
    90                              <2> eldlDataAddresses:	resw 1
    91                              <2> eldlCodeAmount:		resw 1
    92                              <2> eldlCodePrefixes:	resw 1
    93                              <2> eldlCodeEntries:	resw 1
    94                              <2> eldlCodeAddresses:	resw 1
    95                              <2> 	endstruc
    96                              <2> 
    97                              <2> 	numdef ELD_CODE_VSTART, 9001h
    98                              <2> 	numdef ELD_DATA_VSTART, 8000h
    99                              <2> 	numdef ELD_RELOC_VSTART, 8000h
   100                              <2> 
   101                              <2> 	numdef ELD_RECLAIM_HINT, 0
   102                              <2> 	strdef ELD_LISTING, ""
   103                              <2> 	numdef ELD_DATETIME, 0
   104                              <2> 
   105                              <2> %if _ELD_DATETIME
   106                              <2>  %define PUT_ELDHX_DATETIME_OFFSET at eldhxDateTimeOffset, dd DATAOFFSET + datetime - datastart
   107                              <2>  %macro PUT_ELD_DATETIME 0.nolist
   108                              <2> datetime:	asciz __UTC_DATE__,'T',__UTC_TIME__,'Z'
   109                              <2> 		asciz		; for future extension
   110                              <2>  %endmacro
   111                              <2> %else
   112                              <2>  %define PUT_ELDHX_DATETIME_OFFSET
   113                              <2>  %define PUT_ELD_DATETIME
   114                              <2> %endif
   115                              <2> 
   116                              <2> %endif
    17                              <1> 
    18                              <1> 	cpu 8086
    19                              <1> 
    20                              <1> %if ELDSTRICT
    21                              <1>  %if ELDSTRICTCOUNTER
    22                              <1>   %error Missing relocation
    23                              <1>  %endif
    24                              <1> %endif
    25                              <1> 	eldstrict off		; linker does some relocations
    26                              <1> 
    27                              <1> %ifn ELDCALLCALL_DUMPED
    28                              <1> 	eldcall_dump_callcall ELDCALL_CALLCALL_LIST
    29                              <1> %endif
    30                              <1> 
    31                              <1> 	numdef ELD_IDENTICALISE, 0
    32                              <1> 	numdef ELD_DEBUG, 0
    33                              <1> 	numdef ELD_LINKER_PASSES, 1
    34                              <1> 	strdef LISTING, _ELD_LISTING
    35                              <1> 	numdef ELDCALL_OPTIONAL, ELDCALL_OPTIONAL_STATUS
    36                              <1> 	numdef ELDDATA_OPTIONAL, ELDDATA_OPTIONAL_STATUS
    37                              <1> 	numdef ELDDATA_NEXT, ELDDATA_NEXT_STATUS
    38                              <1> 	numdef ELDCALL_NEXT, ELDCALL_NEXT_STATUS
    39                              <1> %if _ELD_IDENTICALISE
    40                              <1>  ;%assign _ELDCALL_OPTIONAL 1
    41                              <1> %endif
    42                              <1> %ifn _ELDCALL_OPTIONAL
    43                              <1> %assign ELDCALL_OPTIONAL_STATUS 2		; not allowed
    44                              <1> %endif
    45                              <1> ;%ifn _ELDDATA_OPTIONAL
    46                              <1> ;%assign ELDDATA_OPTIONAL_STATUS 2		; not allowed
    47                              <1> ;%endif
    48                              <1> 	gendef MAP, ""
    49                              <1> 
    50                              <1> %ifnidni _MAP, ""
    51                              <1>  [map all _MAP]
    52                              <1> %endif
    53                              <1> 
    54                              <1> 
    55                              <1> endresident: equ ($ + _CURRENT_SECTION %+ FIXUP + 15) & ~15
    56                              <1> 
    57                              <1> %if _ELD_LINKER_PASSES
    58                              <1> %assign ELDLINKER 1
    59                              <1> 
    60                              <1> 	struc LINKTABLE
    61 00000000 ????????            <1> ltCodeToCode:	resw 2
    62 00000004 ????????            <1> ltCodeToData:	resw 2
    63 00000008 ????????            <1> ltDataToCode:	resw 2
    64 0000000C ????????            <1> ltDataToData:	resw 2
    65 00000010 ????????            <1> ltLinkData:	resw 2
    66 00000014 ????????            <1> ltLinkCode:	resw 2
    67                              <1> 	endstruc
    68                              <1> %endif
    69                              <1> 
    70                              <1> 
    71                              <1> 		; INP:	es:dx -> loaded initial ELD image
    72                              <1> 		;	 ELD instance structure filled
    73                              <1> 		;	es => ELD code area
    74                              <1> 		;	ds:di -> link info
    75                              <1> 		;	ss:bx -> loaded initial data
    76                              <1> 		;	ss:si -> command line tail
    77                              <1> 		;	cs:ip -> entrypoint
    78                              <1> 		;	ss:sp -> far return address for current mode
    79                              <1> 		; STT:	UP, EI
    80                              <1> linker:
    81                              <1> 		; The first 15 Bytes of the linker should be
    82                              <1> 		;  the same regardless of the linker options
    83                              <1> 		;  used (debug, passes, vstart). This allows
    84                              <1> 		;  the eldcomp ELD to match even if up to 15
    85                              <1> 		;  Bytes of the linker are trailing in the
    86                              <1> 		;  resident part of the ELD.
    87                              <1> 	lframe
    88                              <1>  %if ELDOTHER
    89                              <1> 	lvar dword, linkinfo_other
    90                              <1> 	lvar word, use_hash_other
    91                              <1>  %endif
    92 000002D4 5589E5              <1> 	lenter
    93                              <1> 	lvar dword, instance
    94 000002D7 06                  <1> 	 push es
    95 000002D8 52                  <1> 	 push dx		; -> start of where we're loaded in ELD cs
    96                              <1> 	lvar word, targetsection_low_optional_high
    97 000002D9 50                  <1> 	 push ax		; placeholder
    98                              <1> 	lequ ?targetsection_low_optional_high, targetsection
    99                              <1> 	lequ ?targetsection_low_optional_high + 1, optional
   100                              <1> 	lvar dword, linkinfo
   101 000002DA 1E                  <1> 	 push ds
   102 000002DB 57                  <1> 	 push di		; -> link info (in debugger ss or message seg)
   103                              <1> 	lvar dword, nextreloc
   104 000002DC 06                  <1> 	 push es		; => ELD cs
   105 000002DD 52                  <1> 	 push dx		; placeholder
   106                              <1> 	lvar dword, entry
   107 000002DE 06                  <1> 	 push es		; => ELD cs
   108 000002DF 50                  <1> 	 push ax		; placeholder
   109 000002E0 31C0                <1> 	xor ax, ax
   110 000002E2 813DD1E1            <1> 	cmp word [di + eldlSignature], 0E1D1h
   111                              <1> %if ($ - linker) < 16
   112                              <1>  %error Expected invariant first paragraph of linker
   113                              <1> %endif
   114 000002E6 7403                <1> 	je @F
   115                              <1> .error_j1:
   116 000002E8 E9C602              <1> 	jmp .error		; signature mismatch -->
   117                              <1> @@:
   118 000002EB 837D0601            <1> 	cmp word [di + eldlUseLinkHash], 1
   119 000002EF 77F7                <1> 	ja .error_j1		; unknown use link hash number -->
   120 000002F1 7201                <1> 	jb @F
   121                              <1> %if _ELDDATA_NEXT || _ELDCALL_NEXT
   122                              <1> 	dec al			; = -1 if hash used
   123                              <1> %else
   124 000002F3 48                  <1> 	dec ax
   125                              <1> %endif
   126                              <1> @@:
   127                              <1> 	lvar word, use_hash_low_skip_last_high
   128 000002F4 50                  <1> 	 push ax		; = -1 if hash used, else 0
   129                              <1> 	lequ ?use_hash_low_skip_last_high, use_hash
   130                              <1> 	lequ ?use_hash_low_skip_last_high + 1, skip_last
   131                              <1> %if _ELD_IDENTICALISE && _ELD_LINKER_PASSES
   132                              <1> 	mov ax, linktable - code
   133                              <1> 	lvar word, lt
   134                              <1> 	 push ax		; -> link tables (a single reference)
   135                              <1> %endif
   136                              <1> %if _ELD_LINKER_PASSES || ELDOTHER || _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   137 000002F5 31C0                <1> 	xor ax, ax
   138                              <1>  %if _ELD_LINKER_PASSES
   139                              <1> 	lvar word, pass
   140 000002F7 50                  <1> 	 push ax		; = 0 for linker itself, = 2 for application
   141                              <1> 	lvar word, amounterrors
   142 000002F8 50                  <1> 	 push ax		; how many distinct errors encountered in pass 2
   143                              <1>  %endif
   144                              <1>  %if _ELD_LINKER_PASSES || _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   145                              <1> 	lvar word, name
   146 000002F9 50                  <1> 	 push ax		; -> name currently being sought (in our table)
   147                              <1>  %endif
   148                              <1>  %if ELDOTHER
   149                              <1> 	lvar word, other
   150                              <1> 	 push ax		; byte: 0 = own data links, -1 = other data links
   151                              <1>  %endif
   152                              <1>  %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   153                              <1> 	lvar word, optionalmissing
   154                              <1> 	 push ax
   155                              <1>  %endif
   156                              <1> %endif
   157 000002FA 56                  <1> 	push si			; -> command line tail
   158 000002FB 53                  <1> 	push bx			; -> data block in ELD data area (segment ss)
   159                              <1> 
   160                              <1> 			; simple: add instance base (dx) to code
   161 000002FC 06                  <1> 	push es
   162 000002FD 1F                  <1> 	pop ds			; ds = es => ELD cs
   163                              <1> %if _ELD_LINKER_PASSES
   164                              <1> .pass:
   165 000002FE 8B5EEA              <1> 	mov bx, word [bp + ?pass]	; 0 or 2
   166 00000301 01D3                <1> 	add bx, dx		; -> start of the ELD instance in cs, +0 or +2
   167                              <1>  %if _ELD_IDENTICALISE
   168                              <1> 	add bx, word [bp + ?lt]	; add in single reference to linktable
   169                              <1> 	mov si, word [ltCodeToCode + bx]
   170                              <1>  %else
   171 00000303 8BB74C06            <1> 	mov si, word [linktable - code + ltCodeToCode + bx]
   172                              <1>  %endif
   173                              <1> %else
   174                              <1> 	mov si, internalcodetocoderelocations - code
   175                              <1> %endif		 		; si -> table for code to code (linker or app)
   176 00000307 01D6                <1> 	add si, dx		; relocate the table pointer itself
   177                              <1> @@:
   178 00000309 AD                  <1> 	lodsw
   179 0000030A 85C0                <1> 	test ax, ax		; was last ?
   180 0000030C 740B                <1> 	jz @F			; yes -->
   181 0000030E 93                  <1> 	xchg bx, ax		; bx = entry
   182 0000030F 01D3                <1> 	add bx, dx		; relocate the entry itself
   183                              <1> %if _ELD_CODE_VSTART
   184 00000311 812F[0000]          <1> 	sub word [bx], code	; undo adjustment
   185                              <1> %endif
   186 00000315 0117                <1> 	add word [bx], dx	; relocate word referenced by entry
   187 00000317 EBF0                <1> 	jmp @B
   188                              <1> 
   189                              <1> @@:
   190                              <1> 			; next, add heap data base (on stack) to code
   191                              <1> %if _ELD_LINKER_PASSES
   192 00000319 8B5EEA              <1> 	mov bx, word [bp + ?pass]	; 0 or 2
   193 0000031C 01D3                <1> 	add bx, dx		; -> start of the ELD instance in cs, +0 or +2
   194                              <1>  %if _ELD_IDENTICALISE
   195                              <1> 	add bx, word [bp + ?lt]	; add in single reference to linktable
   196                              <1> 	mov si, word [ltCodeToData + bx]
   197                              <1>  %else
   198 0000031E 8BB75006            <1> 	mov si, word [linktable - code + ltCodeToData + bx]
   199                              <1>  %endif
   200                              <1> %else
   201                              <1> 	mov si, internalcodetodatarelocations - code
   202                              <1> %endif				; si -> table for code to data (linker or app)
   203 00000322 01D6                <1> 	add si, dx		; relocate the table pointer itself
   204                              <1> @@:
   205 00000324 AD                  <1> 	lodsw
   206 00000325 85C0                <1> 	test ax, ax		; was last ?
   207 00000327 740C                <1> 	jz @F			; yes -->
   208 00000329 93                  <1> 	xchg bx, ax		; bx = entry
   209 0000032A 01D3                <1> 	add bx, dx		; relocate the entry itself
   210                              <1> 		; ! access the offset of the data area block, topmost on stack
   211 0000032C 58                  <1> 	pop ax			; ax -> heap data
   212 0000032D 50                  <1> 	push ax
   213                              <1> %if _ELD_DATA_VSTART
   214 0000032E 2D[0000]            <1> 	sub ax, datastart	; undo adjustment
   215                              <1> %endif
   216 00000331 0107                <1> 	add word [bx], ax	; relocate word referenced by entry
   217 00000333 EBEF                <1> 	jmp @B
   218                              <1> 
   219                              <1> @@:
   220                              <1> 
   221                              <1> 			; add instance base (dx) to data
   222                              <1> %if _ELD_LINKER_PASSES
   223 00000335 8B5EEA              <1> 	mov bx, word [bp + ?pass]
   224 00000338 01D3                <1> 	add bx, dx
   225                              <1>  %if _ELD_IDENTICALISE
   226                              <1> 	add bx, word [bp + ?lt]
   227                              <1> 	mov si, word [ltDataToCode + bx]
   228                              <1>  %else
   229 0000033A 8BB75406            <1> 	mov si, word [linktable - code + ltDataToCode + bx]
   230                              <1>  %endif
   231                              <1> %else
   232                              <1> 	mov si, internaldatatocoderelocations - code
   233                              <1> %endif
   234 0000033E 01D6                <1> 	add si, dx
   235                              <1> @@:
   236 00000340 AD                  <1> 	lodsw
   237 00000341 83F8FF              <1> 	cmp ax, -1		; was last ?
   238 00000344 740F                <1> 	je @F			; yes -->
   239 00000346 93                  <1> 	xchg bx, ax		; bx = entry
   240                              <1> 		; ! access the offset of the data area block, topmost on stack
   241 00000347 58                  <1> 	pop ax
   242 00000348 50                  <1> 	push ax
   243 00000349 01C3                <1> 	add bx, ax		; relocate the entry itself
   244                              <1> %if _ELD_CODE_VSTART
   245 0000034B 36812F[0000]        <1> 	sub word [ss:bx], code	; undo adjustment
   246                              <1> %endif
   247 00000350 360117              <1> 	add word [ss:bx], dx	; relocate word referenced by entry
   248 00000353 EBEB                <1> 	jmp @B
   249                              <1> 
   250                              <1> @@:
   251                              <1> 			; next, add heap data base (on stack) to data
   252                              <1> %if _ELD_LINKER_PASSES
   253 00000355 8B5EEA              <1> 	mov bx, word [bp + ?pass]
   254 00000358 01D3                <1> 	add bx, dx
   255                              <1>  %if _ELD_IDENTICALISE
   256                              <1> 	add bx, word [bp + ?lt]
   257                              <1> 	mov si, word [ltDataToData + bx]
   258                              <1>  %else
   259 0000035A 8BB75806            <1> 	mov si, word [linktable - code + ltDataToData + bx]
   260                              <1>  %endif
   261                              <1> %else
   262                              <1> 	mov si, internaldatatodatarelocations - code
   263                              <1> %endif
   264 0000035E 01D6                <1> 	add si, dx
   265                              <1> @@:
   266 00000360 AD                  <1> 	lodsw
   267 00000361 83F8FF              <1> 	cmp ax, -1		; was last ?
   268 00000364 740D                <1> 	je @F			; yes -->
   269 00000366 93                  <1> 	xchg bx, ax		; bx = entry
   270                              <1> 		; ! access the offset of the data area block, topmost on stack
   271 00000367 58                  <1> 	pop ax			; ax -> heap data
   272 00000368 50                  <1> 	push ax
   273 00000369 01C3                <1> 	add bx, ax		; relocate the entry itself
   274                              <1> %if _ELD_DATA_VSTART
   275 0000036B 2D[0000]            <1> 	sub ax, datastart	; undo adjustment
   276                              <1> %endif
   277 0000036E 360107              <1> 	add word [ss:bx], ax	; relocate word referenced by entry
   278 00000371 EBED                <1> 	jmp @B
   279                              <1> 
   280                              <1> @@:
   281 00000373 8B56FC              <1> 	mov dx, word [bp + ?instance]
   282                              <1> 				; reset (why??) -> ELD instance in ELD cs
   283                              <1> %if _ELD_LINKER_PASSES
   284 00000376 8B5EEA              <1> 	mov bx, word [bp + ?pass]
   285 00000379 01D3                <1> 	add bx, dx
   286                              <1>  %if _ELD_IDENTICALISE
   287                              <1> 	add bx, word [bp + ?lt]
   288                              <1> 	add dx, word [ltLinkData + bx]
   289                              <1>  %else
   290 0000037B 03975C06            <1> 	add dx, word [linktable - code + ltLinkData + bx]
   291                              <1>  %endif
   292                              <1> %else
   293                              <1> 	add dx, linkerdatarelocations - code
   294                              <1> %endif
   295                              <1> .otherloop:
   296 0000037F 8956F2              <1> 	mov word [bp + ?nextreloc], dx
   297                              <1> 				; -> data link relocation table
   298                              <1> 
   299                              <1> .datarelocloop:		; must be done before further relocs
   300 00000382 C576F2              <1> 	lds si, [bp + ?nextreloc]
   301 00000385 AD                  <1> 	lodsw			; ax = section indicator
   302 00000386 85C0                <1> 	test ax, ax		; end of table ?
   303 00000388 7503E90401          <1> 	jz .donedatareloc
   304 0000038D 48                  <1> 	dec ax			; al = 1 if data, 0 if code (NB ah may != 0)
   305                              <1> 		; ! access the offset of the data area block, topmost on stack
   306 0000038E 5B                  <1> 	pop bx
   307 0000038F 53                  <1> 	push bx			; bx -> ELD data block
   308 00000390 8946FA              <1> 	mov word [bp + ?targetsection_low_optional_high], ax
   309 00000393 84C0                <1> 	test al, al		; data ?
   310 00000395 AD                  <1> 	lodsw
   311 00000396 7504                <1> 	jnz @F			; yes -->
   312 00000398 0346FC              <1> 	add ax, word [bp + ?instance]
   313                              <1> 				; relocate entry into code
   314 0000039B A9                  <1> 	db __TEST_IMM16		; (skip add)
   315                              <1> @@:
   316 0000039C 01D8                <1> 	add ax, bx		; relocate entry into data
   317 0000039E 8946EE              <1> 	mov word [bp + ?entry], ax
   318                              <1> 				; save away -> where to patch
   319 000003A1 AD                  <1> 	lodsw			; get unrelocated -> name
   320 000003A2 8976F2              <1> 	mov word [bp + ?nextreloc], si
   321                              <1> 				; update -> behind relocation table entry
   322                              <1> %if _ELDDATA_NEXT
   323                              <1> 	rol byte [bp + ?skip_last], 1	; skipping ?
   324                              <1> 	jnc @F				; no -->
   325                              <1> 	test byte [bp + ?optional], 8	; is it a last relocation ?
   326                              <1> 	jz .datarelocloop		; no, leave skip_last set -->
   327                              <1> 	not byte [bp + ?skip_last]	; disable skip_last
   328                              <1> 	jmp .datarelocloop
   329                              <1> @@:
   330                              <1> %endif
   331 000003A5 E8BD00              <1> 	call .build_match	; get ax = scan value, si -> counted string,
   332                              <1> 				;  dl = original value at byte [si]
   333                              <1> 				; NC if symbol already not found before
   334                              <1> 				; CY if to search for the symbol
   335                              <1> %if _ELD_LINKER_PASSES
   336 000003A8 73D8                <1> 	jnc .datarelocloop	; if duplicate of a not found symbol -->
   337                              <1> %endif
   338 000003AA C45EF6              <1> 	les bx, [bp + ?linkinfo]
   339                              <1> %if ELDOTHER
   340                              <1> 	rol byte [bp + ?other], 1
   341                              <1> 	jnc @F
   342                              <1> 	les bx, [bp + ?linkinfo_other]
   343                              <1> @@:
   344                              <1> %endif				; es:bx -> link info table of the ELD host
   345 000003AD 268B4F08            <1> 	mov cx, word [es:bx + eldlDataAmount]	; amount data link info
   346 000003B1 268B7F0A            <1> 	mov di, word [es:bx + eldlDataPrefixes]	; -> prefixes or hashes
   347                              <1> .datarelocfind:
   348 000003B5 83F901              <1> 	cmp cx, 1			; NZ if cx == 0
   349 000003B8 F2AF                <1> 	repne scasw			; scan initial
   350                              <1> %if _ELDDATA_OPTIONAL
   351                              <1> 	jne .datanotfound_may_be_optional
   352                              <1> %else
   353 000003BA 7541                <1> 	jne .datanotfound
   354                              <1> %endif
   355 000003BC 57                  <1> 	push di
   356 000003BD 51                  <1> 	push cx
   357 000003BE 56                  <1> 	push si
   358 000003BF 262B7F0A            <1> 	sub di, word [es:bx + eldlDataPrefixes]	; = double index, 1-based
   359 000003C3 4F                  <1> 	dec di
   360 000003C4 4F                  <1> 	dec di				; 0-based
   361 000003C5 26037F0C            <1> 	add di, word [es:bx + eldlDataEntries]	; -> entry
   362 000003C9 268B3D              <1> 	mov di, [es:di]			; -> counted suffix/string
   363 000003CC B500                <1> 	mov ch, 0
   364 000003CE 8A0C                <1> 	mov cl, byte [si]		; cx = length
   365 000003D0 41                  <1> 	inc cx
   366                              <1> 	; cmp al, al			; ZR if length is zero
   367 000003D1 F3A6                <1> 	repe cmpsb			; match ?
   368 000003D3 5E                  <1> 	pop si
   369 000003D4 59                  <1> 	pop cx
   370 000003D5 5F                  <1> 	pop di
   371 000003D6 75DD                <1> 	jne .datarelocfind		; if not found this time,
   372                              <1> 					;  scan for next initial -->
   373 000003D8 8814                <1> 	mov byte [si], dl		; restore the original byte at counter
   374 000003DA 262B7F0A            <1> 	sub di, word [es:bx + eldlDataPrefixes]	; = double index, 1-based
   375 000003DE 4F                  <1> 	dec di
   376 000003DF 4F                  <1> 	dec di				; 0-based
   377 000003E0 26037F0E            <1> 	add di, word [es:bx + eldlDataAddresses]	; -> address (offset)
   378 000003E4 268B05              <1> 	mov ax, word [es:di]		; get link data from the table
   379 000003E7 E80700              <1> 	call .address_data_reloc
   380                              <1> %if _ELD_RELOC_VSTART
   381 000003EA 2D[0000]            <1> 	sub ax, relocateddata		; *not* a relocation
   382                              <1> %endif
   383 000003ED 0104                <1> 	add word [si], ax		; relocate
   384                              <1> %if _ELDDATA_NEXT
   385                              <1> 	test byte [bp + ?optional], 4	; is it a next relocation ?
   386                              <1> 	jz .datarelocloop
   387                              <1> 	mov byte [bp + ?skip_last], -1	; skip subsequent next/last relocs
   388                              <1> %endif
   389 000003EF EB91                <1> 	jmp .datarelocloop
   390                              <1> 
   391                              <1> .address_data_reloc:
   392 000003F1 C576EE              <1> 	lds si, [bp + ?entry]		; -> entry if in ELD code instance
   393 000003F4 807EFA00            <1> 	cmp byte [bp + ?targetsection], 0
   394                              <1> 					; relocation in code ?
   395 000003F8 7402                <1> 	je @F				; yes -->
   396 000003FA 16                  <1> 	push ss
   397 000003FB 1F                  <1> 	pop ds				; => our ELD data block
   398                              <1> @@:
   399 000003FC C3                  <1> 	retn
   400                              <1> 
   401                              <1> %if _ELDDATA_OPTIONAL
   402                              <1> .datanotfound_may_be_optional:
   403                              <1> 	mov byte [si], dl		; restore the original byte at counter
   404                              <1> %if _ELDDATA_NEXT
   405                              <1> 	test byte [bp + ?optional], 3	; is it an optional relocation ?
   406                              <1> %else
   407                              <1> 	cmp byte [bp + ?optional], 0	; is it an optional relocation ?
   408                              <1> %endif
   409                              <1> %if _ELD_DEBUG
   410                              <1> 	jnz @F
   411                              <1>  %ifn _ELD_LINKER_PASSES
   412                              <1> 	mov si, 0			; (invalid link)
   413                              <1> linkdatarelocation internalflags6
   414                              <1> 	test si, si
   415                              <1> 	jz .datanotfound
   416                              <1> 	mov si, 0			; (invalid link)
   417                              <1> linkdatarelocation options7
   418                              <1> 	test si, si
   419                              <1> 	jz .datanotfound
   420                              <1>  %else
   421                              <1> 	cmp byte [bp + ?pass], 0
   422                              <1> 	je .datanotfound
   423                              <1>  %endif
   424                              <1> 	houdini				; (the above conditions are for this)
   425                              <1> 	jmp .datanotfound
   426                              <1> @@:
   427                              <1> %else
   428                              <1> 	jz .datanotfound		; no, handle as an error -->
   429                              <1> %endif
   430                              <1> 
   431                              <1> %if ELDDATA_PMREQUIRED_STATUS
   432                              <1> 	mov si, relocateddata
   433                              <1> linkdatarelocation build_option_PM
   434                              <1> 	test si, si			; is it a PM build ?
   435                              <1> 	jz @F				; no --> (treat PM required as optional)
   436                              <1> 	test byte [bp + ?optional], 2	; optional status is PM required ?
   437                              <1> 	jnz .datanotfound		; yes, handle as an error -->
   438                              <1> @@:
   439                              <1> %endif
   440                              <1> 
   441                              <1> %if _ELD_LINKER_PASSES
   442                              <1> %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   443                              <1> 	rol byte [bp + ?optionalmissing], 1
   444                              <1> 	jnc .optionaldatamissingmsg
   445                              <1> 	mov si, [bp + ?name]
   446                              <1> 	or byte [si], 80h
   447                              <1> 	not byte [bp + ?optionalmissing]
   448                              <1> 	jmp @F
   449                              <1> .optionaldatamissingmsg:
   450                              <1> %endif
   451                              <1> 	testopt [ss:relocateddata], 2	; debug optional link ?
   452                              <1> linkdatarelocation options7, -3
   453                              <1> 	jz @F				; no -->
   454                              <1> %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   455                              <1> 	mov byte [bp + ?optionalmissing + 1], -1
   456                              <1> %endif
   457                              <1> 	mov si, lmsg.warning_data_optional
   458                              <1> internalcoderelocation
   459                              <1> 	call .notfound			; display a warning
   460                              <1> %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   461                              <1> 	not byte [bp + ?optionalmissing + 1]
   462                              <1> %endif
   463                              <1> @@:
   464                              <1> %endif
   465                              <1> %if _ELDDATA_NEXT
   466                              <1> 	test byte [bp + ?optional], 4	; is it a next relocation ?
   467                              <1> 	jnz .datarelocloop
   468                              <1> %endif
   469                              <1> 	call .address_data_reloc
   470                              <1> 	and word [si], 0		; indicate optional data link failed
   471                              <1> 	jmp .datarelocloop
   472                              <1> %endif
   473                              <1> 
   474                              <1> 
   475                              <1> %if _ELDCALL_OPTIONAL
   476                              <1> .codenotfound_may_be_optional:
   477                              <1> 	mov byte [si], dl		; restore the original byte at counter
   478                              <1> %if _ELDCALL_NEXT
   479                              <1> 	test byte [bp + ?optional], 3	; is it an optional relocation ?
   480                              <1> %else
   481                              <1> 	cmp byte [bp + ?optional], 0	; is it an optional relocation ?
   482                              <1> %endif
   483                              <1> %if _ELD_DEBUG
   484                              <1> 	jnz @F
   485                              <1>  %ifn _ELD_LINKER_PASSES
   486                              <1> 	mov si, 0			; (invalid link)
   487                              <1> linkdatarelocation internalflags6
   488                              <1> 	test si, si
   489                              <1> 	jz .codenotfound
   490                              <1> 	mov si, 0			; (invalid link)
   491                              <1> linkdatarelocation options7
   492                              <1> 	test si, si
   493                              <1> 	jz .codenotfound
   494                              <1>  %else
   495                              <1> 	cmp byte [bp + ?pass], 0
   496                              <1> 	je .codenotfound
   497                              <1>  %endif
   498                              <1> 	houdini				; (the above conditions are for this)
   499                              <1> 	jmp .codenotfound
   500                              <1> @@:
   501                              <1> %else
   502                              <1> 	jz .codenotfound		; no, handle as an error -->
   503                              <1> %endif
   504                              <1> 
   505                              <1> %if ELDCALL_PMREQUIRED_STATUS
   506                              <1>  %if _ELD_LINKER_PASSES
   507                              <1>   %assign ELDLINKER 0
   508                              <1>  %endif
   509                              <1> 	mov si, relocateddata
   510                              <1> linkdatarelocation build_option_PM
   511                              <1>  %if _ELD_LINKER_PASSES
   512                              <1>   %assign ELDLINKER 1
   513                              <1>  %endif
   514                              <1> 	test si, si			; is it a PM build ?
   515                              <1> 	jz @F				; no --> (treat PM required as optional)
   516                              <1> 	test byte [bp + ?optional], 2	; optional status is PM required ?
   517                              <1> 	jnz .codenotfound		; yes, handle as an error -->
   518                              <1> @@:
   519                              <1> %endif
   520                              <1> 
   521                              <1> %if _ELD_LINKER_PASSES
   522                              <1> %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   523                              <1> 	rol byte [bp + ?optionalmissing], 1
   524                              <1> 	jnc .optionalcodemissingmsg
   525                              <1> 	mov si, [bp + ?name]
   526                              <1> 	or byte [si], 80h
   527                              <1> 	not byte [bp + ?optionalmissing]
   528                              <1> 	jmp @F
   529                              <1> .optionalcodemissingmsg:
   530                              <1> %endif
   531                              <1> 	testopt [ss:relocateddata], 2	; debug optional link ?
   532                              <1> linkdatarelocation options7, -3
   533                              <1> 	jz @F				; no -->
   534                              <1> %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   535                              <1> 	mov byte [bp + ?optionalmissing + 1], -1
   536                              <1> %endif
   537                              <1> 	mov si, lmsg.warning_code_optional
   538                              <1> internalcoderelocation
   539                              <1> 	call .notfound			; display a warning
   540                              <1> %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   541                              <1> 	not byte [bp + ?optionalmissing + 1]
   542                              <1> %endif
   543                              <1> @@:
   544                              <1> %endif
   545                              <1> %if _ELDCALL_NEXT
   546                              <1> 	test byte [bp + ?optional], 4	; is it a next relocation ?
   547                              <1> 	jnz .coderelocloop
   548                              <1> %endif
   549                              <1> 	lds si, [bp + ?entry]		; -> code site (must be in ELD cs)
   550                              <1> 	mov word [si], 9090h
   551                              <1> 	mov byte [si + 2], 90h		; indicate optional code link failed
   552                              <1> 					;  (NOP out the 3-byte call near imm)
   553                              <1> 	jmp .coderelocloop
   554                              <1> %endif
   555                              <1> 
   556                              <1> 
   557                              <1> %if _ELD_LINKER_PASSES
   558                              <1> .datanotfound:
   559 000003FD BE[8009]            <1> 	mov si, lmsg.error_data
   560                              <1> internalcoderelocation
   561 00000400 E81900              <1> 	call .notfound			; display error
   562 00000403 7306                <1> 	jnc .error_j3			; NC if in pass 0, error out now -->
   563 00000405 FF46E8              <1> 	inc word [bp + ?amounterrors]	; count the amount of errors
   564 00000408 E977FF              <1> 	jmp .datarelocloop		; go to next relocation entry -->
   565                              <1> 
   566                              <1> .error_j3:
   567 0000040B E9A301              <1> 	jmp .error
   568                              <1> 
   569                              <1> .codenotfound:
   570 0000040E BE[9909]            <1> 	mov si, lmsg.error_code
   571                              <1> internalcoderelocation
   572 00000411 E80800              <1> 	call .notfound			; display error
   573 00000414 73F5                <1> 	jnc .error_j3			; NC if in pass 0 -->
   574 00000416 FF46E8              <1> 	inc word [bp + ?amounterrors]	; count the amount of errors
   575 00000419 E98400              <1> 	jmp .coderelocloop		; go to next -->
   576                              <1> 
   577                              <1> .notfound:
   578 0000041C 807EEA00            <1> 	cmp byte [bp + ?pass], 0	; pass 0 ?
   579 00000420 743A                <1> 	je .notfound.retn		; yes, do not try displaying --> (NC)
   580 00000422 16                  <1> 	 push ss
   581 00000423 07                  <1> 	 pop es
   582 00000424 BF[0000]            <1> 	mov di, relocateddata
   583                              <1> linkdatarelocation line_out		; es:di -> line_out buffer
   584 00000427 E83300              <1> 	call .copy			; copy prefix message
   585 0000042A 8B76E6              <1> 	mov si, word [bp + ?name]
   586 0000042D AD                  <1> 	lodsw				; = hash
   587 0000042E E8[0000]EB020000    <1> 	extcall hexword			; display the hash in hex
   588 00000435 56                  <1> 	push si
   589 00000436 BE[B209]            <1> 	mov si, lmsg.error.2
   590                              <1> internalcoderelocation
   591 00000439 E82100              <1> 	call .copy			; display message fragment
   592 0000043C 5E                  <1> 	pop si
   593                              <1> %if _ELD_LINKER_PASSES
   594 0000043D 56                  <1> 	push si
   595 0000043E E81C00              <1> 	call .copy			; copy over the full name
   596 00000441 5E                  <1> 	pop si
   597                              <1>  %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   598                              <1> 	or byte [si], 80h		; mark as failed optional link
   599                              <1> 	rol byte [bp + ?optionalmissing + 1], 1
   600                              <1> 					; was it optional ?
   601                              <1> 	jc @F				; yes -->
   602                              <1>  %endif
   603 00000442 C60400              <1> 	mov byte [si], 0		; mark as failed (counter byte = 0)
   604                              <1> @@:
   605                              <1> %else
   606                              <1> 	call .copy
   607                              <1> %endif
   608 00000445 B022                <1> 	mov al, '"'
   609 00000447 AA                  <1> 	stosb				; end message with a closing quote mark
   610 00000448 16                  <1> 	 push ss
   611 00000449 1F                  <1> 	 pop ds
   612 0000044A E8[0000]EB020000    <1> 	extcall putsline_crlf		; display diagnostic line
   613 00000451 B8350E              <1> 	mov ax, 0E35h
   614 00000454 E8[0000]EB020000    <1> 	extcall setrc
   615 0000045B F9                  <1> 	stc				; CY, diagnostic displayed
   616                              <1> .notfound.retn:
   617 0000045C C3                  <1> 	retn
   618                              <1> 
   619                              <1> .copy:		; (cannot use extcallcall here)
   620 0000045D E8[0000]EB020000    <1> 	extcall copy_single_counted_string
   621 00000464 C3                  <1> 	retn
   622                              <1> %else
   623                              <1> .datanotfound: equ .error
   624                              <1> .codenotfound: equ .error
   625                              <1> %endif
   626                              <1> 
   627                              <1> .build_match:
   628                              <1> %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   629                              <1> 	mov byte [bp + ?optionalmissing], 0
   630                              <1> 		; This is needed for eldtestj.asm with debugoptlink.
   631                              <1> 		;  The optional data link sets flag 80h, then the
   632                              <1> 		;  required data link to the same symbol sets this
   633                              <1> 		;  flag but doesn't reset it. So the first optional
   634                              <1> 		;  code link still had this set. Reset here to fix.
   635                              <1> %endif
   636                              <1> %if _ELD_CODE_VSTART
   637 00000465 2D[0000]            <1> 	sub ax, code			; revert adjustment (= displacement)
   638                              <1> %endif
   639 00000468 0346FC              <1> 	add ax, word [bp + ?instance]	; make displacement into -> name string
   640 0000046B 96                  <1> 	xchg si, ax			; si -> hash word, counted name string
   641                              <1> %if _ELD_LINKER_PASSES || _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   642 0000046C 8976E6              <1> 	mov word [bp + ?name], si	; save away for diagnostics
   643                              <1> %endif
   644 0000046F AD                  <1> 	lodsw			; = hash, si -> counted string
   645 00000470 8A14                <1> 	mov dl, byte [si]	; dl = original start byte of match
   646                              <1> %if _ELD_LINKER_PASSES
   647 00000472 84D2                <1> 	test dl, dl		; marked as already failed ?
   648                              <1> 				;  (80h = optional, 0 = required)
   649 00000474 750A                <1> 	jnz @F			; no -->
   650 00000476 837EE800            <1> 	cmp word [bp + ?amounterrors], 0
   651                              <1> 				; validate error status
   652 0000047A 7503E9A500          <1> 	je .error_j		; no error known ?! cancel quickly -->
   653 0000047F C3                  <1> 	retn			; (NC)
   654                              <1> 
   655                              <1> @@:
   656                              <1> %else
   657                              <1> 	test dl, dl
   658                              <1> %endif
   659                              <1> %if _ELDDATA_OPTIONAL || _ELDCALL_OPTIONAL
   660                              <1> 	jns @F
   661                              <1> 	and dl, 7Fh
   662                              <1> 	mov byte [si], dl
   663                              <1> 	mov byte [bp + ?optionalmissing], -1
   664                              <1> @@:
   665                              <1> %endif
   666                              <1> %if ELDOTHER
   667                              <1> 	rol byte [bp + ?other], 1
   668                              <1> 	jnc @F
   669                              <1> 	rol byte [bp + ?use_hash_other], 1
   670                              <1> 	jmp @FF
   671                              <1> 
   672                              <1> @@:
   673                              <1> %endif
   674 00000480 D046EC              <1> 	rol byte [bp + ?use_hash], 1
   675                              <1> @@:
   676                              <1> 		; If to use the hash, then ax = hash and si ->
   677                              <1> 		;  the entire symbol name as a counted string.
   678 00000483 720A                <1> 	jc @F			; if to use hash, return now -->
   679 00000485 AC                  <1> 	lodsb			; al = length
   680 00000486 91                  <1> 	xchg cx, ax		; cl = length
   681 00000487 AD                  <1> 	lodsw			; ax = prefix
   682 00000488 49                  <1> 	dec cx
   683 00000489 49                  <1> 	dec cx			; cl = adjusted length
   684 0000048A 4E                  <1> 	dec si			; -> second byte of prefix
   685 0000048B 8A14                <1> 	mov dl, byte [si]	; dl = original start byte of match
   686 0000048D 880C                <1> 	mov byte [si], cl	; si -> counted string suffix
   687                              <1> 		; (this name entry has been edited to provide the
   688                              <1> 		;  name suffix as a counted string, as required by
   689                              <1> 		;  the old-style non-hash link info tables.
   690                              <1> 		; it will be reset later by writing dl to si -> the
   691                              <1> 		;  first byte of the match string.)
   692                              <1> @@:
   693                              <1> %if _ELD_LINKER_PASSES
   694 0000048F F9                  <1> 	stc			; CY
   695                              <1> %endif
   696 00000490 C3                  <1> 	retn
   697                              <1> 
   698                              <1> 
   699                              <1> .donedatareloc:
   700                              <1> %if ELDOTHER
   701                              <1> 	rol byte [bp + ?other], 1
   702                              <1> 	jc .otherdone		; other link only has data links,
   703                              <1> 				;  so at this point we're done -->
   704                              <1> %endif
   705                              <1> 
   706 00000491 8B56FC              <1> 	mov dx, word [bp + ?instance]
   707                              <1> %if _ELD_LINKER_PASSES
   708 00000494 8B5EEA              <1> 	mov bx, word [bp + ?pass]
   709 00000497 01D3                <1> 	add bx, dx
   710                              <1>  %if _ELD_IDENTICALISE
   711                              <1> 	add bx, word [bp + ?lt]
   712                              <1> 	add dx, word [ltLinkCode + bx]
   713                              <1>  %else
   714 00000499 03976006            <1> 	add dx, word [linktable - code + ltLinkCode + bx]
   715                              <1>  %endif
   716                              <1> %else
   717                              <1> 	add dx, linkercoderelocations - code
   718                              <1> %endif
   719 0000049D 8956F2              <1> 	mov word [bp + ?nextreloc], dx
   720                              <1> 
   721                              <1> .coderelocloop:
   722 000004A0 C576F2              <1> 	lds si, [bp + ?nextreloc]
   723 000004A3 AD                  <1> 	lodsw
   724                              <1> %if _ELDCALL_OPTIONAL || _ELDCALL_NEXT
   725                              <1> 	dec ax				; optional word is 1-based, get 0-based
   726                              <1> 	js .donecodereloc
   727                              <1> 	mov word [bp + ?targetsection_low_optional_high], ax
   728                              <1> 	lodsw
   729                              <1> %endif
   730 000004A4 0346FC              <1> 	add ax, word [bp + ?instance]
   731 000004A7 8946EE              <1> 	mov word [bp + ?entry], ax
   732 000004AA AD                  <1> 	lodsw
   733 000004AB 8976F2              <1> 	mov word [bp + ?nextreloc], si
   734                              <1> %ifn _ELDCALL_OPTIONAL || _ELDCALL_NEXT
   735 000004AE 85C0                <1> 	test ax, ax			; if no optional word, check -> match
   736 000004B0 7503E98100          <1> 	jz .donecodereloc
   737                              <1> %endif
   738                              <1> %if _ELDCALL_NEXT
   739                              <1> 	rol byte [bp + ?skip_last], 1	; skipping ?
   740                              <1> 	jnc @F				; no -->
   741                              <1> 	test byte [bp + ?optional], 8	; is it a last relocation ?
   742                              <1> 	jz .coderelocloop		; no, leave skip_last set -->
   743                              <1> 	not byte [bp + ?skip_last]	; disable skip_last
   744                              <1> 	jmp .coderelocloop
   745                              <1> @@:
   746                              <1> %endif
   747 000004B5 E8ADFF              <1> 	call .build_match
   748                              <1> %if _ELD_LINKER_PASSES
   749 000004B8 73E6                <1> 	jnc .coderelocloop
   750                              <1> %endif
   751 000004BA C45EF6              <1> 	les bx, [bp + ?linkinfo]
   752 000004BD 268B4F10            <1> 	mov cx, word [es:bx + eldlCodeAmount]	; amount code link info
   753 000004C1 268B7F12            <1> 	mov di, word [es:bx + eldlCodePrefixes]	; -> prefixes or hashes
   754                              <1> .coderelocfind:
   755 000004C5 83F901              <1> 	cmp cx, 1			; NZ if cx == 0
   756 000004C8 F2AF                <1> 	repne scasw			; scan initial
   757                              <1> %if _ELDCALL_OPTIONAL
   758                              <1> 	jne .codenotfound_may_be_optional
   759                              <1> %else
   760                              <1>  %if _ELD_DEBUG
   761                              <1> 	je @F
   762                              <1> 	houdini
   763                              <1> 	jmp .codenotfound
   764                              <1> @@:
   765                              <1>  %else
   766 000004CA 7403E93FFF          <1> 	jne .codenotfound
   767                              <1>  %endif
   768                              <1> %endif
   769 000004CF 57                  <1> 	push di
   770 000004D0 51                  <1> 	push cx
   771 000004D1 56                  <1> 	push si
   772 000004D2 262B7F12            <1> 	sub di, word [es:bx + eldlCodePrefixes]	; = double index, 1-based
   773 000004D6 4F                  <1> 	dec di
   774 000004D7 4F                  <1> 	dec di				; 0-based
   775 000004D8 26037F14            <1> 	add di, word [es:bx + eldlCodeEntries]	; -> entry
   776 000004DC 268B3D              <1> 	mov di, [es:di]			; -> counted suffix/string
   777 000004DF B500                <1> 	mov ch, 0
   778 000004E1 8A0C                <1> 	mov cl, byte [si]		; cx = length
   779 000004E3 41                  <1> 	inc cx
   780                              <1> 	; cmp al, al			; ZR if length is zero
   781 000004E4 F3A6                <1> 	repe cmpsb			; match ?
   782 000004E6 5E                  <1> 	pop si
   783 000004E7 59                  <1> 	pop cx
   784 000004E8 5F                  <1> 	pop di
   785 000004E9 75DA                <1> 	jne .coderelocfind
   786 000004EB 8814                <1> 	mov byte [si], dl
   787 000004ED 262B7F12            <1> 	sub di, word [es:bx + eldlCodePrefixes]	; = double index, 1-based
   788 000004F1 4F                  <1> 	dec di
   789 000004F2 4F                  <1> 	dec di				; 0-based
   790 000004F3 01FF                <1> 	add di, di			; quadruple index
   791 000004F5 26037F16            <1> 	add di, word [es:bx + eldlCodeAddresses]	; -> address (offset, segment)
   792 000004F9 26FF35              <1> 	push word [es:di]
   793 000004FC C576EE              <1> 	lds si, [bp + ?entry]
   794 000004FF 8F4405              <1> 	pop word [si + 3 + 2]		; call near imm (3), jmp short (2)
   795                              <1> 					;  patch the destination address
   796 00000502 803CE8              <1> 	cmp byte [si], 0E8h		; is it as expected ?
   797 00000505 751D                <1> 	jne .error_j
   798 00000507 268B7D02            <1> 	mov di, word [es:di + 2]
   799 0000050B BB[0000]            <1> 	mov bx, relocateddata
   800                              <1> linkdatarelocation linkcall_table	; ss:bx -> link call table
   801 0000050E 36833F01            <1> 	cmp word [ss:bx], 1		; is it initialised to format 1 ?
   802 00000512 7510                <1> 	jne .error_j			; no -->
   803 00000514 368B4F02            <1> 	mov cx, word [ss:bx + 2]	; get amount of segments
   804 00000518 E30A                <1> 	jcxz .error_j			; none -->
   805                              <1> @@:
   806 0000051A 83C304              <1> 	add bx, 4			; -> next segment
   807 0000051D 36393F              <1> 	cmp word [ss:bx], di		; value matches ?
   808 00000520 7405                <1> 	je @F				; yes, found -->
   809 00000522 E2F6                <1> 	loop @B				; try remaining segments
   810                              <1> .error_j:
   811 00000524 E98A00              <1> 	jmp .error
   812                              <1> 
   813                              <1> @@:
   814 00000527 368B5F02            <1> 	mov bx, word [ss:bx + 2]	; -> call destination offset
   815                              <1> 		; si + 3 + delta = bx
   816                              <1> 		; delta = bx - si - 3
   817 0000052B 29F3                <1> 	sub bx, si
   818 0000052D 83EB03              <1> 	sub bx, 3
   819 00000530 895C01              <1> 	mov word [si + 1], bx		; patch the call instruction
   820                              <1> %if _ELDCALL_NEXT
   821                              <1> 	test byte [bp + ?optional], 4	; is it a next relocation ?
   822                              <1> 	jz .coderelocloop
   823                              <1> 	mov byte [bp + ?skip_last], -1	; skip subsequent next/last relocs
   824                              <1> %endif
   825 00000533 E96AFF              <1> 	jmp .coderelocloop
   826                              <1> 
   827                              <1> .donecodereloc:
   828                              <1> %if _ELD_LINKER_PASSES
   829 00000536 8B46E8              <1> 	mov ax, word [bp + ?amounterrors]
   830 00000539 85C0                <1> 	test ax, ax
   831 0000053B 75E7                <1> 	jnz .error_j
   832 0000053D 8B5EEA              <1> 	mov bx, word [bp + ?pass]
   833 00000540 85DB                <1> 	test bx, bx
   834 00000542 750B                <1> 	jnz @F
   835 00000544 43                  <1> 	inc bx
   836 00000545 43                  <1> 	inc bx
   837 00000546 895EEA              <1> 	mov word [bp + ?pass], bx
   838 00000549 8B56FC              <1> 	mov dx, word [bp + ?instance]
   839 0000054C E9AFFD              <1> 	jmp .pass
   840                              <1> 
   841                              <1> @@:
   842                              <1> %endif
   843                              <1> 
   844                              <1> %ifnidni _LISTING, ""
   845                              <1> %assign ELDLINKER 0
   846                              <1> .hint:
   847 0000054F 16                  <1> 	push ss
   848 00000550 1F                  <1> 	pop ds
   849 00000551 B02D                <1> 	mov al, 2Dh
   850 00000553 E8[0000]EB020000    <1> 	extcall intchk			; ZR if offset = -1 or segment = 0
   851                              <1> 					; CHG: ax, dx, bx
   852 0000055A 7437                <1> 	jz .no_hint
   853                              <1> 
   854                              <1> %if ELDOTHER
   855                              <1> 	mov si, debuggeramissig	; ds:si -> our AMIS name strings
   856                              <1> internalcoderelocation
   857                              <1> %endif
   858                              <1> 
   859 0000055C 8A26[0000]          <1> 	mov ah, byte [relocateddata]
   860                              <1> linkdatarelocation try_debugger_amis_multiplex_number
   861 00000560 E85500              <1> 	call plex_check
   862 00000563 7305                <1> 	jnc @F
   863                              <1> 
   864 00000565 B4FF                <1> 	mov ah, 0FFh		; start with multiplex number 0FFh
   865                              <1> .loop_hint:
   866 00000567 E84E00              <1> 	call plex_check
   867                              <1> @@:
   868 0000056A 7307                <1> 	jnc .end_hint		; if found --> (NC)
   869 0000056C 80EC01              <1> 	sub ah, 1		; search is backward (to find latest installed first), from 0FFh to 00h including
   870 0000056F 73F6                <1> 	jnc .loop_hint		; try next if we didn't check all yet -->
   871 00000571 EB20                <1> 	jmp .no_hint
   872                              <1> 
   873                              <1> .end_hint:
   874 00000573 50                  <1> 	push ax
   875 00000574 C446FC              <1> 	les ax, [bp + ?instance]
   876 00000577 BF[A307]            <1> 	mov di, listmsg.hint.offset
   877                              <1> internalcoderelocation
   878 0000057A E8[0000]EB020000    <1> 	extcall hexword
   879 00000581 BB[8207]            <1> 	mov bx, listmsg.hint
   880                              <1> internalcoderelocation
   881 00000584 368B16[0000]        <1> 	mov dx, [ss:relocateddata]
   882                              <1> linkdatarelocation extseg	; must be 86 Mode segment even in PM
   883 00000589 58                  <1> 	pop ax
   884 0000058A B040                <1> 	mov al, 40h		; AMIS message display service
   885 0000058C E8[0000]EB020000    <1> 	extcall call_int2D
   886                              <1> .no_hint:
   887                              <1> %endif
   888                              <1> 
   889                              <1> %if ELDOTHER
   890                              <1> %assign ELDLINKER 0
   891                              <1> 	not byte [bp + ?other]
   892                              <1> 
   893                              <1> 	push ss
   894                              <1> 	pop ds
   895                              <1> 	mov al, 2Dh
   896                              <1> 	extcall intchk			; ZR if offset = -1 or segment = 0
   897                              <1> 					; CHG: ax, dx, bx
   898                              <1> 	jz .no_other
   899                              <1> 
   900                              <1> 	mov si, debuggeramissig	; ds:si -> our AMIS name strings
   901                              <1> internalcoderelocation
   902                              <1> 
   903                              <1> 	mov ah, byte [relocateddata]
   904                              <1> linkdatarelocation try_debugger_amis_multiplex_number
   905                              <1> 	call plex_check
   906                              <1> 	jnc @F
   907                              <1> 
   908                              <1> 	mov ah, 0FFh		; start with multiplex number 0FFh
   909                              <1> .loop_other_debug:
   910                              <1> 	call plex_check
   911                              <1> @@:
   912                              <1> 	jnc .end_other		; if found --> (NC)
   913                              <1> 	sub ah, 1		; search is backward (to find latest installed first), from 0FFh to 00h including
   914                              <1> 	jnc .loop_other_debug	; try next if we didn't check all yet -->
   915                              <1> 
   916                              <1> 	mov si, loaderamissig	; ds:si -> our AMIS name strings
   917                              <1> internalcoderelocation
   918                              <1> 
   919                              <1> 	mov ah, byte [relocateddata]
   920                              <1> linkdatarelocation try_debugger_amis_multiplex_number
   921                              <1> 	call plex_check
   922                              <1> 	jnc @F
   923                              <1> 
   924                              <1> 	mov ah, 0FFh		; start with multiplex number 0FFh
   925                              <1> .loop_other_loader:
   926                              <1> 	call plex_check
   927                              <1> @@:
   928                              <1> 	jnc .end_other		; if found --> (NC)
   929                              <1> 	sub ah, 1		; search is backward (to find latest installed first), from 0FFh to 00h including
   930                              <1> 	jnc .loop_other_loader	; try next if we didn't check all yet -->
   931                              <1> 
   932                              <1> 	jmp .no_other
   933                              <1> 
   934                              <1> .end_other:
   935                              <1> 	mov al, 42h		; AMIS get other link info service
   936                              <1> 	extcall call_int2D
   937                              <1> 	cmp al, 0FFh
   938                              <1> 	jne .no_other
   939                              <1> 
   940                              <1> 	mov ax, si		; selector => PSP
   941                              <1> 	extcall ispm
   942                              <1> 	jz @F
   943                              <1> 	mov ax, dx		; segment => PSP
   944                              <1> @@:
   945                              <1> 	 push ss
   946                              <1> 	 pop ds
   947                              <1> 	mov word [otherds], ax
   948                              <1> internaldatarelocation		; current mode sel/seg
   949                              <1> 	mov word [otherseg], dx
   950                              <1> internaldatarelocation		; remember segment
   951                              <1> 
   952                              <1> 	mov ax, cx		; selector => link info
   953                              <1> 	extcall ispm
   954                              <1> 	jz @F
   955                              <1> 	mov ax, bx		; segment => link info
   956                              <1> @@:
   957                              <1> 	mov word [bp + ?linkinfo_other], di
   958                              <1> 	mov word [bp + ?linkinfo_other + 2], ax
   959                              <1> 
   960                              <1> 	mov ds, ax		; => link info
   961                              <1> 	xor ax, ax
   962                              <1> 	cmp word [di + eldlSignature], 0E1D1h
   963                              <1> 	jne .error_other
   964                              <1> 	cmp word [di + eldlUseLinkHash], 1
   965                              <1> 	ja .error_other
   966                              <1> 	jb @F
   967                              <1> 	dec ax
   968                              <1> @@:
   969                              <1> 	mov word [bp + ?use_hash_other], ax
   970                              <1> 
   971                              <1> 	mov dx, word [bp + ?instance]
   972                              <1> 	add dx, linkerotherdatarelocations - code
   973                              <1> 	jmp .otherloop
   974                              <1> 
   975                              <1> .error_other:
   976                              <1> 	push cs
   977                              <1> 	pop ds
   978                              <1> 	mov ax, 0E33h
   979                              <1> 	extcall setrc
   980                              <1> 	mov dx, lmsg.error_other
   981                              <1> internalcoderelocation
   982                              <1> 	jmp @F
   983                              <1> 
   984                              <1> .no_other:
   985                              <1> 	push cs
   986                              <1> 	pop ds
   987                              <1> 	mov ax, 0E34h
   988                              <1> 	extcall setrc
   989                              <1> 	mov dx, lmsg.no_other
   990                              <1> internalcoderelocation
   991                              <1> @@:
   992                              <1> 	extcall putsz
   993                              <1> .error_j2:
   994                              <1> 	jmp .error
   995                              <1> 
   996                              <1> .otherdone:
   997                              <1>  %if _ELD_LINKER_PASSES
   998                              <1> 	mov ax, word [bp + ?amounterrors]
   999                              <1> 	test ax, ax
  1000                              <1> 	jnz .error_j2
  1001                              <1>  %endif
  1002                              <1> %endif
  1003                              <1> 
  1004 00000593 5B                  <1> 	pop bx				; -> our heap data
  1005 00000594 5E                  <1> 	pop si				; -> our command line tail
  1006 00000595 16                  <1> 	 push ss
  1007 00000596 1F                  <1> 	 pop ds
  1008 00000597 C47EFC              <1> 	les di, [bp + ?instance]
  1009 0000059A 268B4502            <1> 	mov ax, word [es:di + eldiEndCode]
  1010                              <1> houdini
  1011 0000059E 2D[E002]            <1> 	sub ax, strict word endresident + code
  1012                              <1> internalcoderelocation
  1013 000005A1 26C74502[E002]      <1> 	mov word [es:di + eldiEndCode], endresident + code
  1014                              <1> internalcoderelocation
  1015 000005A7 2906[0000]          <1> 	sub word [relocateddata], ax
  1016                              <1> linkdatarelocation extseg_used
  1017                              <1> %if _DATA_SIZE == 0
  1018                              <1> 	xor ax, ax
  1019                              <1> 	mov word [es:di + eldiStartData], ax
  1020                              <1> 	mov word [es:di + eldiEndData], ax
  1021                              <1> %endif
  1022 000005AB 89EC5D              <1> 	lleave code
  1023                              <1> 		; INP:	es => ELD code segment
  1024                              <1> 		;	ds:si -> command line tail
  1025                              <1> 		;	ds:bx -> ELD data block
  1026                              <1> 		;	ss:sp -> far return address for current mode
  1027                              <1> 		; STT:	ds = ss, UP, EI
  1028 000005AE E96FFC              <1> 	jmp start
  1029                              <1> 
  1030                              <1> .error:
  1031 000005B1 89EC5D              <1> 	lleave
  1032 000005B4 B8FFFF              <1> 	mov ax, -1
  1033 000005B7 CB                  <1> 	retf
  1034                              <1> 
  1035                              <1> 
  1036                              <1> %ifnidni _LISTING, ""
  1037                              <1>  %assign ELDHINT 1
  1038                              <1> %else
  1039                              <1>  %assign ELDHINT 0
  1040                              <1> %endif
  1041                              <1> 
  1042                              <1> %if ELDOTHER || ELDHINT
  1043                              <1> 		; INP:	ah = multiplex number to check
  1044                              <1> 		;	(if ELDOTHER:)
  1045                              <1> 		;	 cs:si -> 16-byte AMIS signature to check
  1046                              <1> 		; OUT:	CY if multiplex number unused or no signature match,
  1047                              <1> 		;	 bp, ah, ds unmodified
  1048                              <1> 		;	NC if match found,
  1049                              <1> 		;	 ah = multiplex number (unmodified)
  1050                              <1> 		; CHG:	di, es, cx, dx
  1051                              <1> 		;	(if ELDOTHER:) bx
  1052                              <1> 		;	(if not ELDOTHER:) si
  1053                              <1> plex_check:
  1054 000005B8 16                  <1> 	push ss
  1055 000005B9 1F                  <1> 	pop ds
  1056 000005BA F606[0000]08        <1> 	testopt [relocateddata], 8
  1057                              <1> linkdatarelocation internalflags4, -3
  1058 000005BF 740B                <1> 	jz @F
  1059                              <1> %if ELDOTHER
  1060                              <1> 	mov bx, relocateddata
  1061                              <1> linkdatarelocation amis_multiplex_number, -2, optional
  1062                              <1> 	test bx, bx
  1063                              <1> 	jz @F
  1064                              <1> 	cmp ah, byte [bx]
  1065                              <1> 	je .notfound		; do not use our own multiplexer -->
  1066                              <1> %else
  1067 000005C1 BE[0000]            <1> 	mov si, relocateddata
  1068                              <1> linkdatarelocation amis_multiplex_number, -2, optional
  1069 000005C4 85F6                <1> 	test si, si
  1070 000005C6 7404                <1> 	jz @F
  1071 000005C8 3A24                <1> 	cmp ah, byte [si]
  1072 000005CA 7420                <1> 	je .notfound		; do not use our own multiplexer -->
  1073                              <1> %endif
  1074                              <1> @@:
  1075 000005CC B000                <1> 	mov al, 00h		; AMIS installation check
  1076 000005CE E8[0000]EB020000    <1> 	extcall call_int2D	; AMIS (or "DOS reserved" = iret if no AMIS present)
  1077 000005D5 3CFF                <1> 	cmp al, 0FFh
  1078 000005D7 7513                <1> 	jne .notfound
  1079 000005D9 0E                  <1> 	push cs
  1080 000005DA 1F                  <1> 	pop ds
  1081                              <1> %if ELDOTHER
  1082                              <1> 	push si
  1083                              <1> 	extcall setes2dx	; es:di -> name strings of AMIS multiplexer that just answered
  1084                              <1> 	mov cx, 8		; Ignore description, only compare vendor and program name
  1085                              <1> 	repe cmpsw
  1086                              <1> 	pop si
  1087                              <1> %else
  1088 000005DB BE[7207]            <1> 	mov si, debuggeramissig	; ds:si -> our AMIS name strings
  1089                              <1> internalcoderelocation
  1090 000005DE E8[0000]EB020000    <1> 	extcall setes2dx	; es:di -> name strings of AMIS multiplexer that just answered
  1091 000005E5 B90800              <1> 	mov cx, 8		; Ignore description, only compare vendor and program name
  1092 000005E8 F3A7                <1> 	repe cmpsw
  1093                              <1> %endif
  1094 000005EA 7401                <1> 	je .checkret		; ZR, NC = match -->
  1095                              <1> .notfound:
  1096 000005EC F9                  <1> 	stc			; CY no match
  1097                              <1> .checkret:
  1098 000005ED C3                  <1> 	retn
  1099                              <1> %endif
  1100                              <1> 
  1101                              <1> 
  1102 000005EE 00<rep 2h>          <1> 	align 4, db 0
  1103                              <1> linkercoderelocations:
  1104                              <1> %if _ELDCALL_OPTIONAL || _ELDCALL_NEXT
  1105                              <1> 	dw ELDCALL_CODE_RELOCATIONS_OPTIONAL, 0
  1106                              <1> %else
  1107 000005F0 2200[AB07]F200-     <1> 	dw ELDCALL_CODE_RELOCATIONS, 0, 0
  1107 000005F6 [BA07]DC01[CC07]E8- <1>
  1107 000005FD 01[D407]F001[E007]- <1>
  1107 00000604 F801[EC07]0002-     <1>
  1107 0000060A [F507]0802[FC07]10- <1>
  1107 00000611 02[0408]1802[0B08]- <1>
  1107 00000618 3302[FC07]6402-     <1>
  1107 0000061E [EC07]5305[4A08]7A- <1>
  1107 00000625 05[1308]8C05[5308]- <1>
  1107 0000062C CE05[5308]DE05-     <1>
  1107 00000632 [6008]00000000      <1>
  1108                              <1> %endif
  1109                              <1> 
  1110                              <1> %if _ELD_LINKER_PASSES
  1111                              <1> linkerlinkercoderelocations:
  1112                              <1> %if _ELDCALL_OPTIONAL || _ELDCALL_NEXT
  1113                              <1> 	dw ELDCALL_LINKER_CODE_RELOCATIONS_OPTIONAL, 0
  1114                              <1> %else
  1115 00000638 2E04[1308]4A04-     <1> 	dw ELDCALL_LINKER_CODE_RELOCATIONS, 0, 0
  1115 0000063E [1D08]5404[0B08]5D- <1>
  1115 00000645 04[2D08]00000000    <1>
  1116                              <1> %endif
  1117                              <1> 
  1118                              <1> 	align 2, db 0
  1119                              <1> linktable:
  1120                              <1> 	istruc LINKTABLE
  1121                              <1> at ltCodeToCode
  1122 0000064C 6407                <1> 	dw internallinkercodetocoderelocations - code
  1123 0000064E FC06                <1> 	dw internalcodetocoderelocations - code
  1124                              <1> at ltCodeToData
  1125 00000650 6C07                <1> 	dw internallinkercodetodatarelocations - code
  1126 00000652 2607                <1> 	dw internalcodetodatarelocations - code
  1127                              <1> at ltDataToCode
  1128 00000654 6E07                <1> 	dw internallinkerdatatocoderelocations - code
  1129 00000656 5207                <1> 	dw internaldatatocoderelocations - code
  1130                              <1> at ltDataToData
  1131 00000658 7007                <1> 	dw internallinkerdatatodatarelocations - code
  1132 0000065A 5407                <1> 	dw internaldatatodatarelocations - code
  1133                              <1> at ltLinkData
  1134 0000065C 5607                <1> 	dw linkerlinkerdatarelocations - code
  1135 0000065E 6406                <1> 	dw linkerdatarelocations - code
  1136                              <1> at ltLinkCode
  1137 00000660 3806                <1> 	dw linkerlinkercoderelocations - code
  1138 00000662 F005                <1> 	dw linkercoderelocations - code
  1139                              <1> 	iend
  1140                              <1> %endif
  1141                              <1> 
  1142                              <1> 	align 2, db 0
  1143                              <1> linkerdatarelocations:
  1144 00000664 01004600[6B08]0100- <1> 	dw LINK_DATA_RELOCATIONS, 0
  1144 0000066C 4800[7508]01004B00- <1>
  1144 00000674 [7E08]0100C000-     <1>
  1144 0000067A [8E08]0100FF00-     <1>
  1144 00000680 [A308]01000801-     <1>
  1144 00000686 [AE08]01002401-     <1>
  1144 0000068C [B708]01004E01-     <1>
  1144 00000692 [B708]01007B01-     <1>
  1144 00000698 [CA08]01009F01-     <1>
  1144 0000069E [CA08]01002902-     <1>
  1144 000006A4 [E008]01004302-     <1>
  1144 000006AA [EE08]01005302-     <1>
  1144 000006B0 [F908]01006002-     <1>
  1144 000006B6 [0709]01007702-     <1>
  1144 000006BC [F908]01007B02-     <1>
  1144 000006C2 [CA08]01009602-     <1>
  1144 000006C8 [CA08]01009C02-     <1>
  1144 000006CE [B708]0100B102-     <1>
  1144 000006D4 [B708]0100B702-     <1>
  1144 000006DA [EE08]01005E05-     <1>
  1144 000006E0 [3209]01008705-     <1>
  1144 000006E6 [AE08]0100A905-     <1>
  1144 000006EC [F908]0100BC05-     <1>
  1144 000006F2 [5709]0101C205-     <1>
  1144 000006F8 [6809]0000          <1>
  1145                              <1> 
  1146                              <1> 	align 2, db 0
  1147                              <1> internalcodetocoderelocations:
  1148 000006FC BC0019016F017601C3- <1> 	dw INTERNAL_CODE_TO_CODE_RELOCATIONS, 0
  1148 00000705 014A024F0257025C02- <1>
  1148 0000070E 73027E02910298029F- <1>
  1148 00000717 02B302780582059F05- <1>
  1148 00000720 A505DC050000        <1>
  1149                              <1> 
  1150                              <1> 	align 2, db 0
  1151                              <1> internalcodetodatarelocations:
  1152 00000726 3400560080009500A3- <1> 	dw INTERNAL_CODE_TO_DATA_RELOCATIONS, 0
  1152 0000072F 00B300B900C300C700- <1>
  1152 00000738 D700DE00E700EC000F- <1>
  1152 00000741 01C701D8013102BD02- <1>
  1152 0000074A C402C902CE020000    <1>
  1153                              <1> 
  1154                              <1> 	align 2, db 0
  1155                              <1> internaldatatocoderelocations:
  1156 00000752 FFFF                <1> 	dw INTERNAL_DATA_TO_CODE_RELOCATIONS, -1
  1157                              <1> 
  1158                              <1> 	align 2, db 0
  1159                              <1> internaldatatodatarelocations:
  1160 00000754 FFFF                <1> 	dw INTERNAL_DATA_TO_DATA_RELOCATIONS, -1
  1161                              <1> 
  1162                              <1> %if _ELD_LINKER_PASSES
  1163                              <1> 	align 2, db 0
  1164                              <1> linkerlinkerdatarelocations:
  1165 00000756 01002504[1609]0100- <1> 	dw LINK_LINKER_DATA_RELOCATIONS, 0
  1165 0000075E 0C05[2109]0000      <1>
  1166                              <1> 
  1167                              <1> 	align 2, db 0
  1168                              <1> internallinkercodetocoderelocations:
  1169 00000764 FE030F0437040000    <1> 	dw INTERNAL_LINKER_CODE_TO_CODE_RELOCATIONS, 0
  1170                              <1> 
  1171                              <1> 	align 2, db 0
  1172                              <1> internallinkercodetodatarelocations:
  1173 0000076C 0000                <1> 	dw INTERNAL_LINKER_CODE_TO_DATA_RELOCATIONS, 0
  1174                              <1> 
  1175                              <1> 	align 2, db 0
  1176                              <1> internallinkerdatatocoderelocations:
  1177 0000076E FFFF                <1> 	dw INTERNAL_LINKER_DATA_TO_CODE_RELOCATIONS, -1
  1178                              <1> 
  1179                              <1> 	align 2, db 0
  1180                              <1> internallinkerdatatodatarelocations:
  1181 00000770 FFFF                <1> 	dw INTERNAL_LINKER_DATA_TO_DATA_RELOCATIONS, -1
  1182                              <1> %endif
  1183                              <1> 
  1184                              <1> %if ELDOTHER
  1185                              <1> 	align 2, db 0
  1186                              <1> linkerotherdatarelocations:
  1187                              <1> 	dw LINK_OTHER_DATA_RELOCATIONS, 0
  1188                              <1> 
  1189                              <1>  %ifnidn LINK_OTHER_LINKER_DATA_RELOCATIONS, ""
  1190                              <1>   %error Other linker data links not supported
  1191                              <1>  %endif
  1192                              <1> %endif
  1193                              <1> 
  1194                              <1> %if ELDOTHER || ELDHINT
  1195                              <1> 	align 2, db 0
  1196                              <1> debuggeramissig:
  1197 00000772 65636D20<rep 5h>    <1> 		fill 8, 32, db "ecm"
  1198 0000077A 6C446562756720-     <1> 		fill 8, 32, db "lDebug"
  1198 0000077A <rep 2h>            <1>
  1199                              <1> %endif
  1200                              <1> 
  1201                              <1> %if ELDOTHER
  1202                              <1> 	align 2, db 0
  1203                              <1> loaderamissig:
  1204                              <1> 		fill 8, 32, db "ecm"
  1205                              <1> 		fill 8, 32, db "Loader"
  1206                              <1> %endif
  1207                              <1> 
  1208                              <1> %ifnidni _LISTING, ""
  1209                              <1> listmsg:
  1210 00000782 547261634C6973742D- <1> .hint:		db "TracList-add-offset=",_LISTING,"::"
  1210 0000078B 6164642D6F66667365- <1>
  1210 00000794 743D616D69736D7367- <1>
  1210 0000079D 2E6C73743A3A        <1>
  1211 000007A3 2D2D2D2D680D0A00    <1> .hint.offset:	asciz "----h",13,10
  1212                              <1> %endif
  1213                              <1> 
  1214 000007AB 30CD0C636D64335F6E- <1> 	eldcall_dump_names ELDCALL_CODE_NAMES
  1214 000007B4 6F745F65787422580F- <1>
  1214 000007BD 636D64335F6E6F745F- <1>
  1214 000007C6 696E6A656374A7AA05- <1>
  1214 000007CF 6572726F72D5550973- <1>
  1214 000007D8 6B6970636F6D6D6103- <1>
  1214 000007E1 C3096973737472696E- <1>
  1214 000007EA 673FDDB90663686B65- <1>
  1214 000007F3 6F6CBABD04636D6433- <1>
  1214 000007FC 551205707574737A28- <1>
  1214 00000805 90046973706DB21205- <1>
  1214 0000080E 736574726384810768- <1>
  1214 00000817 6578776F72646FA20D- <1>
  1214 00000820 707574736C696E655F- <1>
  1214 00000829 63726C66D0BB1A636F- <1>
  1214 00000832 70795F73696E676C65- <1>
  1214 0000083B 5F636F756E7465645F- <1>
  1214 00000844 737472696E67986906- <1>
  1214 0000084D 696E7463686B21300A- <1>
  1214 00000856 63616C6C5F696E7432- <1>
  1214 0000085F 44B774087365746573- <1>
  1214 00000868 326478              <1>
  1215 0000086B C30B076C617374636D- <1> 	link_data_dump_names LINK_DATA_NAMES
  1215 00000874 646B5D06646D79636D- <1>
  1215 0000087D 6454400D6D73672E75- <1>
  1215 00000886 6E696E7374616C6C3B- <1>
  1215 0000088F 26126578745F696E6A- <1>
  1215 00000898 6563745F68616E646C- <1>
  1215 000008A1 6572EB420865787464- <1>
  1215 000008AA 7373656CD52D066578- <1>
  1215 000008B3 74736567C001106578- <1>
  1215 000008BC 745F616D69735F6861- <1>
  1215 000008C5 6E646C657297B61365- <1>
  1215 000008CE 78745F636F6D6D616E- <1>
  1215 000008D7 645F68616E646C6572- <1>
  1215 000008E0 8D710B6D73672E696E- <1>
  1215 000008E9 7374616C6C5ABC086F- <1>
  1215 000008F2 7074696F6E7337E7D3- <1>
  1215 000008FB 0B6578747365675F75- <1>
  1215 00000904 736564B2400C657874- <1>
  1215 0000090D 646174615F75736564- <1>
  1215 00000916 84E3086C696E655F6F- <1>
  1215 0000091F 757468440E6C696E6B- <1>
  1215 00000928 63616C6C5F7461626C- <1>
  1215 00000931 65F09E227472795F64- <1>
  1215 0000093A 656275676765725F61- <1>
  1215 00000943 6D69735F6D756C7469- <1>
  1215 0000094C 706C65785F6E756D62- <1>
  1215 00000955 6572CB510E696E7465- <1>
  1215 0000095E 726E616C666C616773- <1>
  1215 00000967 34688C15616D69735F- <1>
  1215 00000970 6D756C7469706C6578- <1>
  1215 00000979 5F6E756D626572      <1>
  1216                              <1> %if ELDOTHER
  1217                              <1> 	link_data_dump_names LINK_OTHER_DATA_NAMES
  1218                              <1> %endif
  1219                              <1> 
  1220                              <1> lmsg:
  1221                              <1> %if _ELD_LINKER_PASSES
  1222                              <1> %if _ELDCALL_OPTIONAL
  1223                              <1> .warning_code_optional:		counted "Optional code link missing, hash="
  1224                              <1> %endif
  1225                              <1> %if _ELDDATA_OPTIONAL
  1226                              <1> .warning_data_optional:		counted "Optional data link missing, hash="
  1227                              <1> %endif
  1228 00000980 1844617461206C696E- <1> .error_data:			counted "Data link missing, hash="
  1228 00000989 6B206D697373696E67- <1>
  1228 00000992 2C20686173683D      <1>
  1229 00000999 18436F6465206C696E- <1> .error_code:			counted "Code link missing, hash="
  1229 000009A2 6B206D697373696E67- <1>
  1229 000009AB 2C20686173683D      <1>
  1230 000009B2 0A682C206C6162656C- <1> .error.2:			counted "h, label ",'"'
  1230 000009BB 2022                <1>
  1231                              <1> %endif
  1232                              <1> %if ELDOTHER
  1233                              <1> .no_other:		asciz "ELD linker: No other link info found!",13,10
  1234                              <1> .error_other:		asciz "ELD linker: Other link info unknown format!",13,10
  1235                              <1> %endif
  1236                              <1> 
  1237 000009BD 00<rep 3h>          <1> 	align 16, db 0
   581                                  
   582                                  	align 16
   583                                  code_size equ $ - code
