     1                                  
     2                                  %if 0
     3                                  
     4                                  lDOS iniload packed payload
     5                                   by E. C. Masloch, 2018-2020
     6                                  
     7                                  Usage of the works is permitted provided that this
     8                                  instrument is retained with the works, so that any entity
     9                                  that uses the works is notified of this instrument.
    10                                  
    11                                  DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    12                                  
    13                                  
    14                                  Includes one of several depackers, some of which are under
    15                                  separate usage conditions. Refer to the individual depacker
    16                                  source files for the applicable usage conditions.
    17                                  
    18                                  %endif
    19                                  
    20                                  %include "lmacros3.mac"
     1                              <1> [list -]
    14                              <2> [list -]
    14                              <1> [list -]
    21                                  
    22                                  	struc LOADSTACKVARS, -10h
    23 FFFFFFF0 ????????                lsvFirstCluster:	resd 1
    24 FFFFFFF4 ????????                lsvFATSector:		resd 1
    25 FFFFFFF8 ????                    lsvFATSeg:		resw 1
    26 FFFFFFFA ????                    lsvLoadSeg:		resw 1
    27 FFFFFFFC ????????                lsvDataStart:		resd 1
    28                                  	endstruc
    29                                  
    30                                  	struc LOADDATA, LOADSTACKVARS - 10h
    31 FFFFFFE0 ????                    ldMemoryTop:	resw 1
    32 FFFFFFE2 ????                    ldLoadTop:	resw 1
    33 FFFFFFE4 ????                    ldSectorSeg:	resw 1
    34 FFFFFFE6 ??                      ldFATType:	resb 1
    35 FFFFFFE7 ??                      ldHasLBA:	resb 1
    36 FFFFFFE8 ????                    ldClusterSize:	resw 1
    37 FFFFFFEA ????                    ldParaPerSector:resw 1
    38 FFFFFFEC ????                    ldLoadingSeg:	resw 1
    39 FFFFFFEE ????                    ldLoadUntilSeg:	resw 1
    40                                  	endstruc
    41                                  
    42                                  
    43                                  %ifndef _MAP
    44                                  %elifempty _MAP
    45                                  %else	; defined non-empty, str or non-str
    46                                  	[map all _MAP]
    47                                  %endif
    48                                  
    49                                  	defaulting
    50                                  
    51                                  	numdef DEBUG0		; use errordata to generate an error code
    52                                  	numdef DEBUG1		; dump_stack_frame after an error occurred
    53                                  	numdef DEBUG2		; dump_stack_frame before blz_depack_safe call
    54                                  	numdef DEBUG3		; dump_stack_frame at start of blz_depack_safe
    55                                  
    56                                  	numdef OPTIMISE_INPUT_SMALL,	0
    57                                  	numdef OPTIMISE_OUYPUT_SMALL,	0
    58                                  	numdef ALLOW_OVERLAPPING,	1	; allow overlapping src and dst
    59                                  	numdef TEST_PROGRAM,		0
    60                                  	numdef TEST_PROGRAM_DECOMPRESSED_SIZE,		0,0
    61                                  %if _TEST_PROGRAM && ! _TEST_PROGRAM_DECOMPRESSED_SIZE
    62                                   %error Test program has to learn of decompressed size.
    63                                  %endif
    64                                  	numdef TEST_PROGRESS,	0
    65                                  
    66                                  	numdef INCLUDE_UNCOMPRESSED
    67                                  	numdef INCLUDE_UNCOMPRESSED_IN_IMAGE, 1
    68                                  	numdef WRITE_WRONG_FILE
    69                                  	numdef RELOAD_XMS, 0
    70                                  	numdef RELOAD_FILE, 0
    71                                  
    72                                  	numdef EXEC_OFFSET,	0
    73                                  	numdef EXEC_SEGMENT,	0
    74                                  	numdef IMAGE_EXE,	0
    75                                  %if ! _IMAGE_EXE && _TEST_PROGRAM
    76                                   %error Test program can only be used as EXE.
    77                                  %endif
    78                                  	numdef IMAGE_EXE_CS,	-16	; relative-segment for CS
    79                                  	numdef IMAGE_EXE_IP,	256 +64	; value for IP
    80                                  		; The next two are only used if _IMAGE_EXE_AUTO_STACK is 0.
    81                                  	numdef IMAGE_EXE_SS,	-16	; relative-segment for SS
    82                                  	numdef IMAGE_EXE_SP,	0FFFEh	; value for SP (0 underflows)
    83                                  	numdef IMAGE_EXE_AUTO_STACK,	0, 2048	; use stack behind image
    84                                  		; _IMAGE_EXE_AUTO_STACK here differs from iniload's def of
    85                                  		;  the same name. This one is only used as a flag; if non-zero,
    86                                  		;  keep the stack given to us by iniload; if zero, set up the
    87                                  		;  stack specified by _IMAGE_EXE_SS and _IMAGE_EXE_SP.
    88                                  	numdef IMAGE_EXE_GET_COM_STACK, 0
    89                                  					; set up stack for flat .COM style entry
    90                                  	numdef DEVICE,			0
    91                                  	gendef DEVICE_NAME,		""
    92                                  	numdef DEVICE_ATTRIBUTE,	8000h
    93                                  	numdef DEVICE_ZERO_ENTRYPOINT,	0
    94                                  	numdef BOOTLDR,		1	; support boot loaded entrypoint
    95                                  
    96                                  	numdef BRIEFLZ,		0
    97                                  	numdef LZ4,		0
    98                                  	numdef SNAPPY,		0
    99                                  	numdef EXODECR,		0
   100                                  	numdef X,		0
   101                                  	numdef HEATSHRINK,	0
   102                                  	numdef LZD,		0
   103                                  	numdef LZO,		0
   104                                  	numdef LZSA2,		0
   105                                  	numdef APL,		0
   106                                  	numdef BZP,		0
   107                                  	numdef ZEROCOMP,	0
   108                                  	numdef MVCOMP,		0
   109                                  	numdef LZEXEDAT,	0
   110                                  %if (!!_BRIEFLZ + !!_LZ4 + !!_SNAPPY + !!_EXODECR + !!_X + !!_HEATSHRINK 	+ !!_LZD + !!_LZO + !!_LZSA2 + !!_APL + !!_BZP + !!_ZEROCOMP 	+ !!_MVCOMP + !!_LZEXEDAT) != 1
   113                                   %fatal Exactly one compression method must be selected.
   114                                  %endif
   115                                  %assign ADDITIONAL_MEMORY 0
   116                                  %if _BRIEFLZ
   117                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.BLZ"
   118                                  %elif _LZ4
   119                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.LZ4"
   120                                  %elif _SNAPPY
   121                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.SZ"
   122                                  %elif _EXODECR
   123                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.EXO"
   124                                  %elif _X
   125                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.X"
   126                                  %elif _HEATSHRINK
   127                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.HS"
   128                                  %elif _LZD
   129                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.LZ"
   130                                  %elif _LZO
   131                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.LZO"
   132                                  %elif _LZSA2
   133                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.SA2"
   134                                  %elif _APL
   135                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.APL"
   136                                  %elif _BZP
   137                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.BZP"
   138                                  %elif _ZEROCOMP
   139                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.ZER"
   140                                  %elif _MVCOMP
   141                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.MV"
   142                                  %elif _LZEXEDAT
   143                                  	strdef PAYLOAD_FILE,	"lDOSLOAD.LZE"
   144                                  %endif
   145                                  	numdef PAYLOAD_KERNEL_MAX_PARAS,	0, 0
   146                                  %if _PAYLOAD_KERNEL_MAX_PARAS && ! (_IMAGE_EXE || _DEVICE)
   147                                   %error Kernel mode max paras requires building dual-mode or triple-mode executable
   148                                  %endif
   149                                  	numdef COUNTER,		0, 32
   150                                  %if (_COUNTER - 1) & _COUNTER
   151                                   %error COUNTER must be a power of two
   152                                  %endif
   153                                  	numdef PROGRESS,	0, 1
   154                                  	numdef PROGRESSAMOUNT,	0, 0
   155                                  	numdef PROGRESSMULTI,	1
   156                                  	numdef PROGRESSVAR,	1
   157                                  	numdef PROGRESSVARNAME, ""
   158                                  	numdef PROGRESSDEFAULT,	0
   159                                  	numdef PROGRESSDEFAULTAPP,	_PROGRESSDEFAULT
   160                                  	numdef PROGRESSDEFAULTDEVICE,	_PROGRESSDEFAULT
   161                                  	numdef PROGRESSDEFAULTBOOT,1
   162                                  	numdef PASSLCFG, 0
   163                                  	numdef LCFG, (_PROGRESS && _PROGRESSMULTI) || _PASSLCFG
   164                                  
   165                                  
   166                                  %define MODULE inicomp
   167                                  	strdef INILOAD_CFG, ""
   168                                  %ifnidn _INILOAD_CFG, ""
   169                                   %include _INILOAD_CFG
     1                              <1> ; File auto-generated, do not edit.
     2                              <1> strdef INILOAD_SIGNATURE, "OS"
     3                              <1> %assign _DEVICE 0
     4                              <1> %ifidni module, lkernpl
     5                              <1>  %define _PAYLOAD_FILE "msbio.bin"
     6                              <1> %endif
     7                              <1> %define _PAYLOAD_BIO_FILE "msbio.bin"
     8                              <1> %define _PAYLOAD_DOS_FILE "empty.bin"
     9                              <1> %ifn _TEST_PROGRAM
    10                              <1>  numdef SECOND_PAYLOAD_EXE, 1
    11                              <1>  strdef SECOND_PAYLOAD_FILE, "tmp/payload2.bin"
    12                              <1>  numdef SECOND_PAYLOAD_EXE_IP, 256
    13                              <1>  numdef SECOND_PAYLOAD_EXE_AUTO_STACK, 2048, 2048
    14                              <1>  numdef SECOND_PAYLOAD_EXE_MIN, 68000
    15                              <1> 
    16                              <1>  numdef SECOND_PAYLOAD_EXE_MAX, 0
    17                              <1>  strdef EXE_TRAIL_INCBIN, "tmp/trail.bin"
    18                              <1> %endif
   170                                  %endif
   171                                  	strdef LCFG_CFG, ""
   172                                  
   173                                  %if _DEVICE
   174                                   %ifidn _DEVICE_NAME, ""
   175                                    %error Device name must be set
   176                                   %endif
   177                                  %endif
   178                                  
   179                                  	struc XMSM
   180 00000000 ????????                .size_:		resd 1
   181 00000004 ????                    .srchdl:	resw 1
   182 00000006 ????????                .srcadr:	resd 1
   183 0000000A ????                    .dsthdl:	resw 1
   184 0000000C ????????                .dstadr:	resd 1
   185                                  	endstruc
   186                                  
   187                                  
   188                                  	cpu 8086
   189                                  	addsection INIT0, start=0 vstart=0
   190                                  init0_start:
   191                                  %if _DEVICE
   192                                  		; The device header is of a fixed format.
   193                                  		;  For our purposes, the 4-byte code for
   194                                  		;  each the strategy entry and the
   195                                  		;  interrupt entry is part of this format.
   196                                  		; (DOS may read the attributes or entrypoint
   197                                  		;  offsets before calling either, so in the inicomp
   198                                  		;  stage we need to recreate in the entrypoints part
   199                                  		;  exactly what the application has here.)
   200                                  		; _PASSLCFG: The lCFG block is passed in the dword
   201                                  		;  behind the interrupt entry.
   202                                  device_header:
   203                                  .next:
   204                                   %if _DEVICE_ZERO_ENTRYPOINT
   205                                  	fill 2, -1, jmp strict short j_zero_entrypoint
   206                                  	dw -1
   207                                   %else
   208                                  	dd -1				; link to next device
   209                                   %endif
   210                                  .attributes:
   211                                  	dw _DEVICE_ATTRIBUTE		; attributes
   212                                  .strategy:
   213                                  	dw .strategy_entry		; -> strategy entry
   214                                  .interrupt:
   215                                  	dw .interrupt_entry		; -> interrupt entry
   216                                  .name:
   217                                  	fill 8, 32, db _DEVICE_NAME	; character device name,
   218                                  					;  or block device number of units
   219                                  					;  + optional name
   220                                  .strategy_entry:
   221                                  	fill 4, 90h, jmp device_entrypoint
   222                                  .interrupt_entry:
   223                                  	fill 4, 90h, retf
   224                                  .pass_lcfg:
   225                                  %endif
   226                                  
   227                                  
   228                                  %if _IMAGE_EXE || _DEVICE
   229 00000000 90                      	nop
   230 00000001 90<rep 1Fh>             	align 32, nop
   231                                  init0_kernel_entry:
   232                                  		; cs:ip = load seg : 32 here
   233                                  %if ($ - $$) != 32
   234                                   %error Wrong kernel mode entrypoint
   235                                  %endif
   236                                  %if _TEST_PROGRAM
   237                                  @@:
   238 00000020 CC                      	int3
   239 00000021 FB                      	sti
   240 00000022 F4                      	hlt
   241 00000023 EBFB                    	jmp @B
   242                                  %endif
   243                                  %if _BOOTLDR
   244                                  %if ! _IMAGE_EXE
   245                                  j_zero_entrypoint:
   246                                  %endif
   247 00000025 31DB                    	xor bx, bx		; 0 = kernel mode
   248 00000027 50                      	push ax
   249 00000028 8CC8                    	mov ax, cs
   250 0000002A 83C040                  	add ax, (init0_end - init0_start) >> 4
   251 0000002D 8B56E2                  	mov dx, word [ bp + ldLoadTop ]	; => after end of available space
   252 00000030 BE6000                  	mov si, 60h		; => destination
   253 00000033 EB7E                    	jmp init0_common
   254                                  %endif
   255                                  
   256                                   %if _IMAGE_EXE
   257 00000035 90<rep Bh>              	align 64, nop
   258                                  j_zero_entrypoint:
   259                                  init0_exe_entry:
   260                                  		; NOTE:	This part is called with ip = 256 + 64, cs = PSP.
   261                                  %if ($ - $$) != 64
   262                                   %error Wrong EXE mode entrypoint
   263                                  %endif
   264                                  %if _IMAGE_EXE_GET_COM_STACK
   265                                  	mov bx, ds		; => PSP
   266                                  	dec bx			; => MCB
   267                                  	mov ds, bx
   268                                  	add bx, word [3]	; add size of memory block
   269                                  	sub bx, -1 + paras(512)	; add one, then subtract enough paragraphs
   270                                  	cli
   271                                  	mov ss, bx
   272                                  	mov sp, 512		; -> new stack
   273                                  	sti
   274                                  %endif
   275 00000040 BB0100                  	mov bx, 1		; EXE mode
   276 00000043 50                      	push ax
   277                                    %if _TEST_PROGRAM
   278                                  %if (_INCLUDE_UNCOMPRESSED && ! _INCLUDE_UNCOMPRESSED_IN_IMAGE) || _RELOAD_FILE
   279                                  	push ds
   280                                  	mov ax, word [2Ch]	; => environment
   281                                  	test ax, ax
   282                                  	jnz @F
   283                                  .errorfile:
   284                                  	jmp init0_error_file
   285                                  @@:
   286                                  	mov ds, ax
   287                                  	mov cx, 8000h
   288                                  	xor si, si		; -> environment
   289                                  @@:
   290                                  	lodsb
   291                                  	test al, al
   292                                  	loopnz @B		; si -> past one NUL
   293                                  	jcxz .errorfile
   294                                  	cmp byte [si], 0	; -> another NUL ?
   295                                  	loopne @B		; no, skip next variable -->
   296                                  	jcxz .errorfile
   297                                  	inc si			; skip double NUL
   298                                  	lodsw			; load amount strings after environment
   299                                  	cmp ax, 1		; 1 ?
   300                                  	jne .errorfile		; no -->
   301                                  	mov dx, si		; ds:dx -> executable pathname
   302                                  	mov ax, 3D00h + 0_010_0_000b	; deny write, read only
   303                                  	int 21h			; open
   304                                  	jc .errorfile
   305                                  	pop ds			; restore => PSP
   306                                  	push ax			; push into ?handle
   307                                  %endif
   308                                  
   309 00000044 BE8100                  	mov si, 81h
   310 00000047 31D2                    	xor dx, dx
   311 00000049 31C0                    	xor ax, ax
   312                                  cmdline:
   313                                  .:
   314 0000004B AC                      	lodsb
   315 0000004C 3C09                    	cmp al, 9
   316 0000004E 74FB                    	je .
   317 00000050 3C20                    	cmp al, 32
   318 00000052 74F7                    	je .
   319 00000054 3C0D                    	cmp al, 13
   320 00000056 744E                    	je .end
   321 00000058 3C30                    	cmp al, '0'
   322 0000005A 721E                    	jb .notdigit
   323 0000005C 3C39                    	cmp al, '9'
   324 0000005E 771A                    	ja .notdigit
   325                                  .digit:
   326 00000060 2C30                    	sub al, '0'
   327 00000062 89D1                    	mov cx, dx		; times 1
   328 00000064 01D2                    	add dx, dx
   329 00000066 722A                    	jc .invalid
   330 00000068 01D2                    	add dx, dx		; times 4
   331 0000006A 7226                    	jc .invalid
   332 0000006C 01CA                    	add dx, cx		; times 5
   333 0000006E 7222                    	jc .invalid
   334 00000070 01D2                    	add dx, dx		; times 10
   335 00000072 721E                    	jc .invalid
   336 00000074 01C2                    	add dx, ax		; add in low digit
   337 00000076 721A                    	jc .invalid
   338 00000078 EBD1                    	jmp .
   339                                  
   340                                  .notdigit:
   341 0000007A 3C41                    	cmp al, 'A'
   342 0000007C 7419                    	je .a
   343 0000007E 3C61                    	cmp al, 'a'
   344 00000080 7415                    	je .a
   345 00000082 3C42                    	cmp al, 'B'
   346 00000084 7416                    	je .b
   347 00000086 3C62                    	cmp al, 'b'
   348 00000088 7412                    	je .b
   349 0000008A 3C43                    	cmp al, 'C'
   350 0000008C 7413                    	je .c
   351 0000008E 3C63                    	cmp al, 'c'
   352 00000090 740F                    	je .c
   353                                  .invalid:
   354 00000092 BAFFFF                  	mov dx, -1		; invalid
   355 00000095 EB0F                    	jmp .end
   356                                  
   357                                  .a:
   358 00000097 80E77F                  	and bh, ~ 80h		; A mode. determine min alloc size
   359 0000009A EBAF                    	jmp .
   360                                  
   361                                  .b:
   362 0000009C 80CF80                  	or bh, 80h		; B mode. repeat depack, counter in command line
   363 0000009F EBAA                    	jmp .
   364                                  
   365                                  .c:
   366 000000A1 80CF40                  	or bh, 40h		; C mode. how often would the counter be called
   367 000000A4 EBA5                    	jmp .
   368                                  
   369                                  .end:
   370                                  				; bx for ?whichtest
   371 000000A6 52                      	push dx			; for ?repetitions
   372                                    %endif
   373 000000A7 8CD2                    	mov dx, ss		; => after end of available space
   374 000000A9 8CC8                    	mov ax, cs
   375 000000AB 83C050                  	add ax, (256 + (init0_end - init0_start)) >> 4	; => source
   376 000000AE 8CCE                    	mov si, cs
   377 000000B0 83C610                  	add si, 256 >> 4	; => destination
   378                                   %endif
   379                                  
   380                                  init0_common:
   381                                  		; REM:	This part must be position-independent, as it is
   382                                  		;	 called either with ip = init0_common (kernel mode
   383                                  		;	 or device mode)
   384                                  		;	 or ip = init0_common + 256 (application mode).
   385                                  		; INP:	si => depack destination
   386                                  		;	ax => source of payload + INIT1
   387                                  		;	dx => behind available memory
   388                                  		; OUT:	cs:ip -> init1_start:
   389                                  		;	ax => INIT1
   390                                  		;	dx => payload source
   391                                  		;	si => depack destination
   392                                  		;	bx = mode
   393 000000B3 FC                      	cld
   394                                  %if _TEST_PROGRAM
   395                                   %ifn _RELOAD_XMS || _RELOAD_FILE
   396 000000B4 81EAE90E                	sub dx, ( (payload_end - payload) ) >> 4
   397 000000B8 721A                    	jc .error
   398                                   %endif
   399 000000BA B99923                  	mov cx, ( 		+ (init0b_end - init0b_start) 		+ (payload_end - payload) 		+ (init1_end - init1_start) 		+ (init2_end - init2_start) 		) >> 4
   405 000000BD 29CA                    	sub dx, cx
   406 000000BF 7213                    	jc .error
   407 000000C1 39C2                    	cmp dx, ax
   408 000000C3 720F                    	jb .error
   409                                  %else
   410                                  	mov cx, ( 		+ (init0b_end - init0b_start) 		+ (payload_end - payload) 		+ (init1_end - init1_start) 		) >> 4
   415                                  				; cx = amount paragraphs in INIT0B + payload + INIT1
   416                                  	sub dx, cx		; => destination for INIT0B + payload + INIT1
   417                                  				;  (highest possible spot in available memory)
   418                                  %endif
   419 000000C5 56                      	push si			; preserve destination
   420 000000C6 E86700                  	call init0_movp		; move up payload + INIT1
   421 000000C9 5E                      	pop si
   422                                  %else
   423                                  	cld
   424                                  	mov ax, cs
   425                                  	add ax, (init0_end - init0_start) >> 4
   426                                  	mov cx, ( 		+ (init0b_end - init0b_start) 		+ (payload_end - payload) 		+ (init1_end - init1_start) 		) >> 4
   431                                  	mov dx, word [ bp + ldLoadTop ]
   432                                  	sub dx, cx
   433                                  	call init0_movp
   434                                  %endif
   435                                  
   436                                  %if _LCFG && ! _TEST_PROGRAM
   437                                  	push cs
   438                                  	call @F			; position-independent far pointer
   439                                  @@:
   440                                  	pop ax
   441                                  	add ax, lcfg - @B	; -> lCFG block
   442                                  	push ax
   443                                  %endif
   444                                  
   445 000000CA 89D0                    	mov ax, dx		; => INIT0B
   446                                  				;  (same as => payload if INIT0B is empty)
   447                                  %if (_LCFG || _PROGRESS) && ! _TEST_PROGRAM
   448                                  	add dx, ( 		+ (init0b_end - init0b_start) 		) >> 4		; => payload
   451                                  %else
   452                                   %if _TEST_PROGRAM
   453 000000CC 05370F                  	add ax, ( 		+ (init0b_end - init0b_start) 		+ (payload_end - payload) 		+ (init1_end - init1_start) 		) >> 4		; => INIT2
   458                                   %else
   459                                  	add ax, ( 		+ (init0b_end - init0b_start) 		+ (payload_end - payload) 		) >> 4		; => INIT1
   463                                   %endif
   464                                  %endif
   465 000000CF 31C9                    	xor cx, cx
   466 000000D1 50                      	push ax
   467 000000D2 51                      	push cx
   468 000000D3 CB                      	retf			; jump to relocated
   469                                  				;  INIT0B:init0b_start
   470                                  				;  or INIT1:init1_start
   471                                  				;  or INIT2:init2_start
   472                                  
   473                                  
   474                                  %if _TEST_PROGRAM
   475                                  .error:
   476 000000D4 89DF                    	mov di, bx		; whichtest
   477                                  
   478 000000D6 0E                      	push cs
   479 000000D7 1F                      	pop ds
   480 000000D8 BA[B202]                	mov dx, init0_msg.error_stderr + 256
   481 000000DB B92500                  	mov cx, init0_msg.error_stderr.length
   482 000000DE BB0200                  	mov bx, 2
   483 000000E1 B440                    	mov ah, 40h
   484 000000E3 CD21                    	int 21h
   485                                  
   486 000000E5 F7C70040                	test di, 4000h		; whichtest
   487 000000E9 7408                    	jz @F
   488 000000EB BA[D702]                	mov dx, init0_msg.error_c_stdout + 256
   489 000000EE B90300                  	mov cx, init0_msg.error_c_stdout.length
   490 000000F1 EB0A                    	jmp @FF
   491                                  @@:
   492 000000F3 85FF                    	test di, di		; whichtest
   493 000000F5 780D                    	js @FF
   494 000000F7 BA[D702]                	mov dx, init0_msg.error_stdout + 256
   495 000000FA B90300                  	mov cx, init0_msg.error_stdout.length
   496                                  @@:
   497 000000FD BB0100                  	mov bx, 1
   498 00000100 B440                    	mov ah, 40h
   499 00000102 CD21                    	int 21h
   500                                  @@:
   501 00000104 B8FF4C                  	mov ax, 4CFFh
   502 00000107 CD21                    	int 21h
   503                                  
   504                                  %if (_INCLUDE_UNCOMPRESSED && ! _INCLUDE_UNCOMPRESSED_IN_IMAGE) || _RELOAD_FILE
   505                                  init0_error_file:
   506                                  	mov dx, init0_msg.error_stderr_file + 256
   507                                  	mov cx, init0_msg.error_stderr_file.length
   508                                  	push cs
   509                                  	pop ds
   510                                  	mov bx, 2
   511                                  	mov ah, 40h
   512                                  	int 21h
   513                                  
   514                                  	mov dx, init0_msg.error_stdout + 256
   515                                  	mov cx, init0_msg.error_stdout.length
   516                                  	mov bx, 1
   517                                  	mov ah, 40h
   518                                  	int 21h
   519                                  	mov ax, 4CFFh
   520                                  	int 21h
   521                                  %endif
   522                                  
   523                                  %endif
   524                                  
   525                                  
   526                                  %if _LCFG
   527                                  	%imacro lcfgoption 3+.nolist
   528                                  	_fill %1, 0, lcfg
   529                                  %%start:
   530                                  	%2
   531                                  	%3
   532                                  %%end:
   533                                  %assign %%index %%start - lcfg
   534                                  %rep %%end - %%start
   535                                  %assign LCFGINUSE LCFGINUSE | (1 << %%index)
   536                                   %assign %%index %%index + 1
   537                                  %endrep
   538                                  	%endmacro
   539                                  %assign LCFGINUSE 0
   540                                  
   541 00000109 90<rep 7h>              	align 16
   542                                  lcfg:
   543 00000110 EB1E                    .:		jmp strict short .end
   544 00000112 6C434647                lcfgoption 2,,	db "lCFG"
   545 00000116 3030                    lcfgoption 6,,	db "00"
   546 00000118 FCFFF50C00000000        lcfgoption 8,,	dq .inuse
   547                                   %if _PROGRESS && _PROGRESSMULTI
   548                                    %if _IMAGE_EXE
   549 00000120 00                      lcfgoption 16, .progress_app:, db _PROGRESSDEFAULTAPP
   550                                    %endif
   551                                    %if _DEVICE
   552                                  lcfgoption 17, .progress_dev:, db _PROGRESSDEFAULTDEVICE
   553                                    %endif
   554                                    %if _BOOTLDR
   555 00000121 0001                    lcfgoption 18, .progress_boot:, db _PROGRESSDEFAULTBOOT
   556                                    %endif
   557                                   %endif
   558                                  
   559                                  %ifnidn _LCFG_CFG, ""
   560                                   %include _LCFG_CFG
     1                              <1> ; File auto-generated, do not edit.
     2                              <1> %include "src/INC/scanptab.mac"
     1                              <2> 
     2                              <2> %if 0
     3                              <2> 
     4                              <2> scanptab - Scan partition table (macros)
     5                              <2>  2019, 2025 by 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> mode_all_ext5			equ 00b
    16                              <2> mode_ignore_ext5		equ 01b
    17                              <2> mode_first_ext5			equ 10b
    18                              <2> mode_first_type_ext5		equ 11b
    19                              <2> 
    20                              <2> mode_all_ext15			equ 00b << 2
    21                              <2> mode_ignore_ext15		equ 01b << 2
    22                              <2> mode_first_ext15		equ 10b << 2
    23                              <2> mode_first_type_ext15		equ 11b << 2
    24                              <2> 
    25                              <2> mode_all_ext85			equ 00b << 4
    26                              <2> mode_ignore_ext85		equ 01b << 4
    27                              <2> mode_first_ext85		equ 10b << 4
    28                              <2> mode_first_type_ext85		equ 11b << 4
    29                              <2> 
    30                              <2> mode_ignore_subsequent_nested	equ            1_00_00_00b
    31                              <2> mode_ignore_subsequent_logical	equ           10_00_00_00b
    32                              <2> mode_ignore_subsequent_primary	equ          100_00_00_00b
    33                              <2> mode_traditional_order_logical	equ         1000_00_00_00b
    34                              <2> mode_active_priority		equ       1_0000_00_00_00b
    35                              <2> mode_subsequent_primary_after	equ      10_0000_00_00_00b
    36                              <2> mode_disable_fat32		equ 00_1000_0000_00_00_00b
    37                              <2> mode_disable_lba		equ 01_0000_0000_00_00_00b
    38                              <2> mode_dlasort_zero		equ 10_0000_0000_00_00_00b
     3                              <1> %include "src/INC/verbose.mac"
     1                              <2> 
     2                              <2> ; Public Domain, 2025 by E. C. Masloch
     3                              <2> 
     4                              <2> verbose_intro	equ 1
     5                              <2> verbose_xms	equ 2
     6                              <2> verbose_cds	equ 4
     4                              <1> %include "src/INC/haltflag.mac"
     1                              <2> 
     2                              <2> ; Public Domain
     3                              <2> 
     4                              <2> flag_no_halt_tagcrash	equ 1
     5                              <2> flag_no_halt_mcb	equ 2
     6                              <2> flag_no_halt_hmcb	equ 4
     7                              <2> flag_no_halt_hmcb_free	equ 8
     5 00000123 0000                <1> lcfgoption 20, .checkdebugger:, db 0
     6 00000125 01                  <1> lcfgoption 21, .verbose:, db verbose_intro
     7 00000126 0000                <1> lcfgoption 22, .scanmode:, dw 0
     8 00000128 00<rep 2h>0C00      <1> lcfgoption 26, .haltflag:, dw 0 | flag_no_halt_hmcb | flag_no_halt_hmcb_free
   561                                  %endif
   562                                  
   563 0000012C 00<rep 4h>              lcfgoption 32,,
   564                                  .end:
   565                                  .size: equ .end - .
   566                                  .inuse equ LCFGINUSE
   567                                  %endif
   568                                  
   569                                  
   570                                  %if _DEVICE
   571                                  device_entrypoint:
   572                                  %if _TEST_PROGRAM
   573                                  @@:
   574                                  	int3
   575                                  	sti
   576                                  	hlt
   577                                  	jmp @B
   578                                  %endif
   579                                  	cmp byte [es:bx + 2], 0		; command code 0 (init) ?
   580                                  	je @F
   581                                  
   582                                  	mov word [es:bx + 3], 8103h	; error, done, code: unknown command
   583                                  	retf
   584                                  
   585                                  @@:
   586                                  	or word [cs:device_header.next], -1
   587                                  	push cs
   588                                  	push word [cs:device_header.strategy]
   589                                  					; -> far return to payload's strategy
   590                                  	push bp
   591                                  	push ds
   592                                  	push si
   593                                  	push di
   594                                  	push dx
   595                                  	push cx
   596                                  	push ax
   597                                  	push bx
   598                                  	push es
   599                                  
   600                                  	mov dx, word [es:bx + 14]
   601                                  	mov cl, 4
   602                                  	shr dx, cl		; = how many full paragraphs (rounded down)
   603                                  	add dx, word [es:bx + 14 + 2]
   604                                  				; ax => behind end
   605                                  
   606                                  	mov di, cs
   607                                  image_size: equ  ( 		+ (init0_end - init0_start) 		+ (init0b_end - init0b_start) 		+ (payload_end - payload) 		+ (init1_end - init1_start) 		)
   613                                  	add di, image_size >> 4		; di => end of image
   614                                  
   615                                  	cmp dx, di			; enough memory to hold all of us ?
   616                                  	jb @F				; no -->
   617                                  				; yes
   618                                  .have_some_memory:
   619                                  				; dx => after end of memory
   620                                  	mov bx, 2		; device mode
   621                                  	push ax
   622                                  	mov ax, cs
   623                                  	add ax, (init0_end - init0_start) >> 4
   624                                  	mov si, cs		; => destination
   625                                  	jmp init0_common
   626                                  
   627                                  
   628                                  @@:
   629                                  	push cs
   630                                  	pop ds
   631                                  	mov dx, .msg_no_memory
   632                                  	mov ah, 09h
   633                                  	int 21h
   634                                  
   635                                  	mov ax, 3000h
   636                                  	int 21h
   637                                  	cmp al, 5
   638                                  	jae @F
   639                                  	mov dx, .msg_dos_below_5
   640                                  	mov ah, 09h
   641                                  	int 21h
   642                                  @@:
   643                                  
   644                                  	mov dx, .msg_linebreak
   645                                  	mov ah, 09h
   646                                  	int 21h
   647                                  
   648                                  		; tear down the stack frame and modify the request header
   649                                  	pop es
   650                                  	pop bx
   651                                  	mov word [es:bx + 3], 8103h	; set error, done, invalid command
   652                                  	mov byte [es:bx + 13], 0	; set number of units = 0
   653                                  	mov word [es:bx + 14 + 2], cs
   654                                  	and word [es:bx + 14], 0	; -> after end of memory to allocate
   655                                  	pop ax
   656                                  	pop cx
   657                                  	pop dx
   658                                  	pop di
   659                                  	pop si
   660                                  	pop ds
   661                                  	pop bp
   662                                  	add sp, 4		; discard far return to payload's strategy
   663                                  	retf			; return to DOS
   664                                  
   665                                  
   666                                  .msg_no_memory:		ascic "Load error: Not enough memory."
   667                                  .msg_dos_below_5:	ascic " Note: DOS must be at least version 5."
   668                                  .msg_linebreak:		ascic 13,10
   669                                  %endif
   670                                  
   671                                  
   672                                  		; Move paragraphs
   673                                  		;
   674                                  		; INP:	ax => source
   675                                  		;	dx => destination
   676                                  		;	cx = number of paragraphs
   677                                  		; CHG:	cx, ds, si, es, di
   678                                  		; OUT:	ax and dx unchanged
   679                                  		; Note:	Doesn't work correctly on HMA; doesn't always wrap to LMA either.
   680                                  		;	Do not provide a wrapped/HMA source or destination!
   681                                  init0_movp:
   682 00000130 39D0                    	cmp ax, dx		; source above destination ?
   683 00000132 770A                    	ja .up			; yes, move up (forwards) -->
   684 00000134 747B                    	je .return		; same, no need to move -->
   685 00000136 50                      	push ax
   686 00000137 01C8                    	add ax, cx		; (expected not to carry)
   687 00000139 39D0                    	cmp ax, dx		; end of source is above destination ?
   688 0000013B 58                      	pop ax
   689 0000013C 7730                    	ja .down		; yes, move from top down -->
   690                                  	; Here, the end of source is below-or-equal the destination,
   691                                  	;  so they do not overlap. In this case we prefer moving up.
   692                                  
   693                                  .up:
   694 0000013E 50                      	push ax
   695 0000013F 52                      	push dx
   696                                  .uploop:
   697 00000140 8ED8                    	mov ds, ax
   698 00000142 8EC2                    	mov es, dx
   699 00000144 31FF                    	xor di, di
   700 00000146 31F6                    	xor si, si		; -> start of segment
   701 00000148 81E90010                	sub cx, 1000h		; 64 KiB left ?
   702 0000014C 7610                    	jbe .uplast		; no -->
   703 0000014E 51                      	push cx
   704 0000014F B90080                  	mov cx, 10000h /2
   705 00000152 F3A5                    	rep movsw		; move 64 KiB
   706 00000154 59                      	pop cx
   707 00000155 050010                  	add ax, 1000h
   708 00000158 81C20010                	add dx, 1000h		; -> next segment
   709 0000015C EBE2                    	jmp short .uploop	; proceed for more -->
   710                                  .uplast:
   711 0000015E 81C10010                	add cx, 1000h		; restore counter
   712 00000162 D1E1                    	shl cx, 1
   713 00000164 D1E1                    	shl cx, 1
   714 00000166 D1E1                    	shl cx, 1		; *8, paragraphs to words
   715 00000168 F3A5                    	rep movsw		; move last part
   716 0000016A 5A                      	pop dx
   717 0000016B 58                      	pop ax
   718 0000016C EB43                    	jmp short .return
   719                                  
   720                                  .down:
   721 0000016E FD                      	std			; _AMD_ERRATUM_109_WORKAROUND as below
   722                                  .dnloop:
   723 0000016F 81E90010                	sub cx, 1000h		; 64 KiB left ?
   724 00000173 761A                    	jbe .dnlast		; no -->
   725 00000175 50                      	push ax
   726 00000176 52                      	push dx
   727 00000177 01C8                    	add ax, cx
   728 00000179 01CA                    	add dx, cx
   729 0000017B 8ED8                    	mov ds, ax		; -> 64 KiB not yet moved
   730 0000017D 8EC2                    	mov es, dx
   731 0000017F 5A                      	pop dx
   732 00000180 58                      	pop ax
   733 00000181 BFFEFF                  	mov di, -2
   734 00000184 89FE                    	mov si, di		; moved from last word down
   735 00000186 51                      	push cx
   736 00000187 B90080                  	mov cx, 10000h /2
   737 0000018A F3A5                    	rep movsw		; move 64 KiB
   738 0000018C 59                      	pop cx
   739 0000018D EBE0                    	jmp short .dnloop	; proceed for more -->
   740                                  .dnlast:
   741 0000018F 81C10010                	add cx, 1000h		; restore counter
   742 00000193 D1E1                    	shl cx, 1
   743 00000195 D1E1                    	shl cx, 1
   744 00000197 D1E1                    	shl cx, 1		; *8, paragraphs to words
   745 00000199 89CF                    	mov di, cx
   746 0000019B 4F                      	dec di
   747 0000019C D1E7                    	shl di, 1		; words to offset, -> last word
   748 0000019E 89FE                    	mov si, di
   749 000001A0 8ED8                    	mov ds, ax
   750 000001A2 8EC2                    	mov es, dx		; first segment correct
   751                                  
   752                                  
   753                                  	numdef AMD_ERRATUM_109_WORKAROUND, 1
   754                                  %if 0
   755                                  
   756                                  Jack R. Ellis pointed out this erratum:
   757                                  
   758                                  Quoting from https://www.amd.com/system/files/TechDocs/25759.pdf page 69:
   759                                  
   760                                  109   Certain Reverse REP MOVS May Produce Unpredictable Behavior
   761                                  
   762                                  Description
   763                                  
   764                                  In certain situations a REP MOVS instruction may lead to
   765                                  incorrect results. An incorrect address size, data size
   766                                  or source operand segment may be used or a succeeding
   767                                  instruction may be skipped. This may occur under the
   768                                  following conditions:
   769                                  
   770                                  * EFLAGS.DF=1 (the string is being moved in the reverse direction).
   771                                  
   772                                  * The number of items being moved (RCX) is between 1 and 20.
   773                                  
   774                                  * The REP MOVS instruction is preceded by some microcoded instruction
   775                                    that has not completely retired by the time the REP MOVS begins
   776                                    execution. The set of such instructions includes BOUND, CLI, LDS,
   777                                    LES, LFS, LGS, LSS, IDIV, and most microcoded x87 instructions.
   778                                  
   779                                  Potential Effect on System
   780                                  
   781                                  Incorrect results may be produced or the system may hang.
   782                                  
   783                                  Suggested Workaround
   784                                  
   785                                  Contact your AMD representative for information on a BIOS update.
   786                                  
   787                                  %endif
   788                                  
   789                                  %if _AMD_ERRATUM_109_WORKAROUND
   790 000001A4 E308                    	jcxz @FF
   791 000001A6 83F914                  	cmp cx, 20
   792 000001A9 7703                    	ja @FF
   793                                  @@:
   794 000001AB A5                      	movsw
   795 000001AC E2FD                    	loop @B
   796                                  @@:
   797                                  %endif
   798 000001AE F3A5                    	rep movsw		; move first part
   799 000001B0 FC                      	cld
   800                                  .return:
   801 000001B1 C3                      	retn
   802                                  
   803                                  
   804                                  	addsection INIT0B, align=16 vstart=0 follows=INIT0
   805                                  		; INP:	ax:cx = cs:ip = cs:0
   806                                  		;	ax => INIT0B
   807                                  		;	dx => payload source
   808                                  		;	ss:sp -> (dword pointer to lCFG block)
   809                                  		;	if app/device mode supported:
   810                                  		;	 si => depack destination
   811                                  		;	 bx = mode
   812                                  init0b_start:
   813                                  %if _LCFG || _PROGRESS
   814                                  
   815 00000000 05FA0E                  	add ax, ( 		+ (init0b_end - init0b_start) 		+ (payload_end - payload) 		) >> 4		; => INIT1
   819                                  
   820                                  %if _LCFG && _PASSLCFG
   821                                   %if (_IMAGE_EXE || _DEVICE)
   822 00000003 89F1                    	mov cx, si		; preserve si
   823                                   %endif
   824 00000005 5E                      	pop si
   825 00000006 1F                      	pop ds			; -> lCFG block
   826 00000007 8EC0                    	mov es, ax
   827 00000009 BF[B003]                	mov di, transfer_lcfg_block
   828                                  				; -> destination
   829                                   %if (_IMAGE_EXE || _DEVICE)
   830 0000000C 51                      	push cx
   831                                   %endif
   832 0000000D 57                      	push di
   833 0000000E B91000                  	mov cx, words(lcfg.size)
   834 00000011 F3A5                    	rep movsw		; cx = 0
   835 00000013 5F                      	pop di			; es:di -> relocated lCFG block, same difference
   836                                   %if (_IMAGE_EXE || _DEVICE)
   837 00000014 5E                      	pop si			; preserve si
   838                                   %endif
   839                                  %elif _LCFG
   840                                  	pop di
   841                                  	pop es			; es:di -> (original) lCFG block
   842                                  %endif
   843                                  
   844 00000015 50                      	push ax
   845 00000016 51                      	push cx			; -> far return address to init1_start
   846                                  
   847                                  %if _PROGRESS && _PROGRESSMULTI
   848                                   %if (_IMAGE_EXE || _DEVICE)
   849 00000017 56                      	push si
   850 00000018 53                      	push bx
   851                                   %endif
   852                                   %if _BOOTLDR
   853                                    %if _LCFG
   854 00000019 31C0                    	xor ax, ax
   855 0000001B 268A4512                	mov al, byte [es:di + lcfg.progress_boot - lcfg]
   856 0000001F 97                      	xchg di, ax		; di = boot default progress
   857                                  				; es:ax -> lCFG block
   858                                    %else			; _LCFG
   859                                  	mov di, _PROGRESSDEFAULTBOOT
   860                                    %endif		; _LCFG
   861                                   %endif			; _BOOTLDR
   862                                   %if (_IMAGE_EXE || _DEVICE)
   863                                    %if _BOOTLDR
   864 00000020 85DB                    	test bx, bx
   865 00000022 7503E9A700              	jz .default
   866                                    %endif		; _BOOTLDR
   867                                    %if _LCFG
   868 00000027 06                      	push es
   869                                     %if _BOOTLDR
   870 00000028 50                      	push ax			; -> lCFG block
   871                                     %else		; _BOOTLDR
   872                                  	push di
   873                                     %endif		; _BOOTLDR
   874                                    %endif		; _LCFG
   875                                    %if _PROGRESSVAR
   876 00000029 B451                    	mov ah, 51h
   877 0000002B CD21                    	int 21h
   878                                  @@:
   879 0000002D 8EDB                    	mov ds, bx
   880 0000002F A12C00                  	mov ax, word [2Ch]
   881 00000032 85C0                    	test ax, ax
   882 00000034 7510                    	jnz .gotenv
   883 00000036 A11600                  	mov ax, word [16h]
   884 00000039 40                      	inc ax
   885 0000003A 7469                    	jz .default_nonboot
   886 0000003C 48                      	dec ax
   887 0000003D 7466                    	jz .default_nonboot
   888 0000003F 39C3                    	cmp bx, ax
   889 00000041 7462                    	je .default_nonboot
   890 00000043 93                      	xchg bx, ax
   891 00000044 EBE7                    	jmp @B
   892                                  
   893                                  .gotenv:
   894 00000046 0E                      	push cs
   895 00000047 1F                      	pop ds				; => cs
   896 00000048 8EC0                    	mov es, ax			; => environment
   897                                   %ifnidni _PROGRESSVARNAME, ""
   898 0000004A BB[FA00]                	mov bx, progressvarname1
   899 0000004D E80C00                  	call .findenv
   900 00000050 732E                    	jnc .foundenv			; match -->
   901 00000052 BB[FD00]                	mov bx, progressvarname2
   902                                   %endif
   903 00000055 E80400                  	call .findenv
   904 00000058 7326                    	jnc .foundenv			; match -->
   905 0000005A EB49                    	jmp .default_nonboot
   906                                  
   907                                  .findenv:
   908 0000005C 31FF                    	xor di, di
   909                                  @@:
   910                                   %ifnidni _PROGRESSVARNAME, ""
   911 0000005E 89DE                    	mov si, bx			; -> variable name
   912                                   %else
   913                                  	mov si, progressvarname2	; -> variable name
   914                                   %endif
   915 00000060 31C0                    	xor ax, ax
   916 00000062 AC                      	lodsb				; get length
   917 00000063 91                      	xchg cx, ax			; cx = length
   918 00000064 57                      	push di
   919 00000065 F3A6                    	repe cmpsb			; match ?
   920 00000067 7415                    	je .findret_pop			; (NC) yes -->
   921 00000069 5F                      	pop di
   922 0000006A B90080                  	mov cx, 8000h			; maximum env size
   923 0000006D 29F9                    	sub cx, di			; any left ?
   924 0000006F 760B                    	jbe .findret_CY			; no -->
   925 00000071 B000                    	mov al, 0
   926 00000073 F2AE                    	repne scasb			; find next NUL
   927 00000075 7505                    	jne .findret_CY
   928 00000077 263805                  	cmp byte [es:di], al		; double NUL ?
   929 0000007A 75E2                    	jne @B				; no, loop -->
   930                                  .findret_CY:
   931 0000007C F9                      	stc				; not found
   932 0000007D C3                      	retn
   933                                  
   934                                  .findret_pop:
   935 0000007E 59                      	pop cx
   936 0000007F C3                      	retn
   937                                  
   938                                  .foundenv:
   939                                  %if _LCFG
   940 00000080 5E                      	pop si
   941 00000081 5E                      	pop si				; discard far pointer to lCFG
   942                                  %endif
   943 00000082 89FE                    	mov si, di			; es:si -> var content
   944 00000084 31FF                    	xor di, di			; = 0
   945 00000086 31C0                    	xor ax, ax			; ah = 0
   946                                  @@:
   947 00000088 26AC                    	es lodsb			; next candidate digit
   948 0000008A 2C30                    	sub al, '0'			; digit ?
   949 0000008C 7212                    	jb @F				; no -->
   950 0000008E 3C09                    	cmp al, 9
   951 00000090 770E                    	ja @F				; no -->
   952 00000092 01FF                    	add di, di			; times 2
   953 00000094 89FB                    	mov bx, di
   954 00000096 01FF                    	add di, di			; times 4
   955 00000098 01FF                    	add di, di			; times 8
   956 0000009A 01DF                    	add di, bx			; times 8 + times 2 = times 10
   957 0000009C 01C7                    	add di, ax			; add in next digit
   958 0000009E EBE8                    	jmp @B				; and loop
   959                                  
   960                                  @@:
   961 000000A0 83E71F                  	and di, 31			; mask to low 5 bits
   962 000000A3 EB0B                    	jmp @F
   963                                    %endif	; _PROGRESSVAR
   964                                  
   965                                  .default_nonboot:
   966                                  %if _LCFG
   967 000000A5 5F                      	pop di
   968 000000A6 07                      	pop es			; -> lCFG block
   969 000000A7 5B                      	pop bx			; = 1 if app, = 2 if device
   970 000000A8 53                      	push bx
   971 000000A9 268B4510                	mov ax, word [es:di + lcfg.progress_app - lcfg]
   972                                   %if _DEVICE
   973                                    %if lcfg.progress_app + 1 != lcfg.progress_dev
   974                                     %error Unexpected layout
   975                                    %endif
   976                                  				; al = app, ah = device
   977                                  	dec bx
   978                                  	jz .default_app
   979                                  	xchg al, ah		; al = device
   980                                  .default_app:
   981                                   %endif			; _DEVICE
   982 000000AD B400                    	mov ah, 0		; ax = default
   983 000000AF 97                      	xchg di, ax		; di = default
   984                                  %else			; _LCFG
   985                                  	mov di, _PROGRESSDEFAULT
   986                                  %endif			; _LCFG
   987                                  @@:
   988 000000B0 F7C71000                	test di, 16
   989 000000B4 7405                    	jz @F
   990 000000B6 83E7EF                  	and di, ~16
   991 000000B9 EB13                    	jmp .outputdevice	; if 16 set skip device check
   992                                  @@:
   993 000000BB 52                      	push dx
   994 000000BC B80044                  	mov ax, 4400h		; IOCTL get device information
   995 000000BF BB0100                  	mov bx, 1		; StdOut
   996 000000C2 B283                    	mov dl, 83h		; default if 21.4400 fails
   997 000000C4 CD21                    	int 21h
   998 000000C6 F6C280                  	test dl, 80h
   999 000000C9 5A                      	pop dx
  1000 000000CA 7502                    	jnz .outputdevice
  1001 000000CC 31FF                    	xor di, di		; stdout is a file: force no progress marker
  1002                                  .outputdevice:
  1003                                   %endif			; (_IMAGE_EXE || _DEVICE)
  1004                                  
  1005                                  .default:
  1006                                   %if (_IMAGE_EXE || _DEVICE)
  1007 000000CE 5B                      	pop bx
  1008 000000CF 5E                      	pop si
  1009                                   %endif
  1010 000000D0 83FF05                  	cmp di, step_progress_table.amount
  1011                                  					; valid ?
  1012 000000D3 7202                    	jb @F				; yes -->
  1013 000000D5 31FF                    	xor di, di			; disable
  1014                                  @@:
  1015 000000D7 D1E7                    	shl di, 1			; = word index
  1016 000000D9 59                      	pop cx				; = 0
  1017 000000DA 1F                      	pop ds				; ds => INIT1
  1018                                  
  1019 000000DB 2E8B85[F000]            	mov ax, word [cs:step_progress_table + di]
  1020                                  					; ax = rel16 for step progress handler
  1021 000000E0 1E                      	push ds
  1022 000000E1 51                      	push cx				; -> init1_start
  1023 000000E2 A3[7200]                	mov word [step_progress.handler], ax
  1024                                  					; patch it
  1025                                  
  1026 000000E5 83FF04                  	cmp di, 2 * 2			; none or dots ?
  1027 000000E8 7305                    	jae @F				; no, skip -->
  1028 000000EA C606[0600]A9            	mov byte [..@empty_step_progress], __TEST_IMM16
  1029                                  					; for none and dots do not call here
  1030                                  @@:
  1031                                  %endif			;  _PROGRESS && _PROGRESSMULTI
  1032 000000EF CB                      	retf
  1033                                  %endif
  1034                                  
  1035                                  %if _PROGRESS && _PROGRESSMULTI
  1036                                  		align 2, db 0
  1037                                  step_progress_table:
  1038                                  .:
  1039 000000F0 1600                    		dw step_progress.0_step - step_progress.base
  1040 000000F2 3B00                    		dw step_progress.1_step - step_progress.base
  1041 000000F4 0000                    		dw step_progress.2_step - step_progress.base
  1042 000000F6 4100                    		dw step_progress.3_step - step_progress.base
  1043 000000F8 8600                    		dw step_progress.4_step - step_progress.base
  1044                                  .amount equ ($ - .) / 2
  1045                                  
  1046                                   %if _PROGRESSVAR && (_IMAGE_EXE || _DEVICE)
  1047                                    %ifnidni _PROGRESSVARNAME, ""
  1048 000000FA 02003D                  progressvarname1:	counted _PROGRESSVARNAME, '='
  1049                                    %endif
  1050 000000FD 0D4C444F5350524F47-     progressvarname2:	counted "LDOSPROGRESS="
  1050 00000106 524553533D         
  1051                                   %endif
  1052                                  %endif
  1053                                  
  1054 0000010B 90<rep 5h>              	align 16
  1055                                  init0b_end:
  1056                                  
  1057                                  
  1058                                  	addsection PAYLOAD, align=16 follows=INIT0B
  1059                                  payload:
  1060 00000000 <bin EE8Bh>             	incbin _PAYLOAD_FILE
  1061                                  .end:
  1062 0000EE8B 26<rep 5h>              	align 16, db 38
  1063                                  payload_end:
  1064                                  
  1065                                  %if _OPTIMISE_INPUT_SMALL
  1066                                   %ifn (payload_end - payload) <= 65_520
  1067                                    %error Input declared small is not small
  1068                                   %endif
  1069                                  %else
  1070                                   %if (payload_end - payload) <= 65_520
  1071                                    %warning Input could be declared small
  1071          ******************       warning: Input could be declared small [-w+user]
  1072                                   %endif
  1073                                  %endif
  1074                                  
  1075                                  
  1076                                  	addsection INIT1, align=16 follows=PAYLOAD vstart=0
  1077                                  init1_start:
  1078                                  		; INP:	ax = cs = INIT1
  1079                                  		;	dx = cs - (payload_end - payload) >> 4 => source data
  1080                                  		;	if kernel mode:
  1081                                  		;	 ss:bp -> LOADDATA and LOADSTACKVARS
  1082                                  		;	 ss:sp -> valid stack above [bp + ldLoadTop]
  1083                                  		;	 60h => destination
  1084                                  		;	any mode:
  1085                                  		;	 ss:sp -> word value for ax
  1086                                  		;	 bx = 2 if device mode, 1 if EXE mode, 0 if kernel mode
  1087                                  		;	 si => destination (60h for kernel mode,
  1088                                  		;		after PSP for EXE mode,
  1089                                  		;		at device header for device mode)
  1090                                  		;		(not set if only kernel mode supported)
  1091                                  		;	 if EXE mode:
  1092                                  		;	  ss:sp -> valid stack above INIT1
  1093                                  		;	  bp = unset
  1094                                  		;	 if device mode:
  1095                                  		;	  ss:sp -> device entrypoint stack
  1096                                  		;	  holds: es, bx, ax, cx, dx, di, si, ds, bp,
  1097                                  		;		  far address of payload strategy entrypoint,
  1098                                  		;		  far return address to DOS
  1099                                  		;	  bp = unset
  1100                                  		; STT:	UP
  1101                                  		; CHG:	ax, bx, cx, dx, es, ds, si, di
  1102                                  %if _IMAGE_EXE || _DEVICE
  1103                                  	lframe
  1104 00000000 5589E5                  	lenter
  1105                                  	lvar word,	exemode		; must be bp - 2!
  1106 00000003 53                      	 push bx
  1107                                   %if ?exemode != -2
  1108                                    %error exemode variable must be directly below bp
  1109                                   %endif
  1110 00000004 56                      	push si
  1111                                   %if _PROGRESS
  1112 00000005 F8                      	clc			; NC
  1113                                   %endif
  1114                                  %else
  1115                                  	xor bx, bx		; always tell them it is kernel mode (NC)
  1116                                  %endif
  1117                                  
  1118                                  %if _PROGRESS
  1119                                  	; clc
  1120                                  ..@empty_step_progress:		; SMC, byte patched to __TEST_IMM16 if none or dots
  1121                                   %if _TEST_PROGRAM
  1122 00000006 90<rep 3h>              	times 3 nop
  1123                                   %else
  1124                                  	call step_progress.CF	; display empty / 0.0%
  1125                                   %endif
  1126                                  @@:
  1127                                  %endif
  1128                                  
  1129                                  %if _IMAGE_EXE || _DEVICE
  1130 00000009 8EC6                    	mov es, si		; es => destination
  1131                                  %else
  1132                                  	mov ax, 60h
  1133                                  	mov es, ax		; es => destination
  1134                                  %endif
  1135 0000000B 31FF                    	xor di, di		; -> destination
  1136                                  
  1137 0000000D 8EDA                    	mov ds, dx
  1138 0000000F 31F6                    	xor si, si		; -> source
  1139                                  
  1140 00000011 B98BEE                  	mov cx, (payload.end - payload) & 0FFFFh
  1141                                  %if (payload.end - payload) >> 16
  1142                                  	mov dx, (payload.end - payload) >> 16	; = length of source
  1143                                  %else
  1144 00000014 31D2                    	xor dx, dx
  1145                                  %endif
  1146                                  %if _PAYLOAD_KERNEL_MAX_PARAS
  1147                                  	mov ax, _PAYLOAD_KERNEL_MAX_PARAS
  1148                                  	test bx, bx
  1149                                  	jz @F
  1150                                  %endif
  1151 00000016 B8FFFF                  	mov ax, -1
  1152                                  @@:
  1153                                  
  1154                                  		; INP:	ds:si -> source
  1155                                  		;	dx:cx = length of source
  1156                                  		;	es:di -> destination (below source)
  1157                                  		;	bx = EXE mode flag
  1158                                  		;	 (1 if EXE mode, 0 if kernel mode)
  1159                                  		;	 (always 0 if this is a build without EXE mode)
  1160                                  		;	if _PAYLOAD_KERNEL_MAX_PARAS:
  1161                                  		;	 ax = maximum amount in paragraphs of destination needed
  1162                                  		;	 (-1 if full source should be decompressed)
  1163                                  		;	else:
  1164                                  		;	 ax = -1
  1165                                  		; Note:	The destination reaches up to below the source.
  1166 00000019 E8E701                  	call depack
  1167                                  %ifn _TEST_PROGRAM
  1168                                  	jc strict short error	; -2 (replaced by retf \ nop)
  1169                                  %endif
  1170                                  %if _IMAGE_EXE || _DEVICE
  1171 0000001C 5E                      	pop si			; si
  1172                                   %if _TEST_PROGRAM
  1173 0000001D 58                      	pop ax			; (discard ?exemode, leave bx as returned)
  1174                                   %else
  1175                                  	pop bx			; ?exemode
  1176                                   %endif
  1177 0000001E 5D                      	pop bp			; bp
  1178 0000001F 58                      	pop ax			; ax
  1179                                  	lleave ctx
  1180                                  %endif
  1181                                  %if _TEST_PROGRAM
  1182 00000020 CB                      	retf			; +1 (replace jc error)
  1183 00000021 90                      	nop			; +1
  1184                                  %endif
  1185                                  
  1186                                  %if _DEVICE
  1187                                  	test bl, 2
  1188                                  	jz .jmp_exe_or_kernel_mode
  1189                                  
  1190                                  .jmp_device_mode:
  1191                                  	mov ds, si
  1192                                  	or word [device_header.next], -1
  1193                                  %if _LCFG && _PASSLCFG
  1194                                  	mov word [device_header.pass_lcfg], transfer_lcfg_block
  1195                                  	mov word [device_header.pass_lcfg + 2], cs
  1196                                  %endif
  1197                                  	pop es
  1198                                  	pop bx
  1199                                  	pop ax
  1200                                  	pop cx
  1201                                  	pop dx
  1202                                  	pop di
  1203                                  	pop si
  1204                                  	pop ds
  1205                                  	pop bp
  1206                                  	retf			; transfer to payload strategy entrypoint
  1207                                  				; still on stack: far return address to DOS
  1208                                  
  1209                                  .jmp_exe_or_kernel_mode:
  1210                                  %endif
  1211                                  
  1212                                  %if _IMAGE_EXE
  1213 00000022 F6C301                  	test bl, 1
  1214 00000025 7415                    	jz .jmp_kernel_mode
  1215                                  
  1216                                  .jmp_exe_mode:
  1217                                  %if ! _IMAGE_EXE_AUTO_STACK
  1218                                  	mov cx, cs
  1219                                  	lea dx, [si + _IMAGE_EXE_SS]
  1220                                  	push dx			; stack = relocated ss value
  1221                                  	add dx, (_IMAGE_EXE_SP + 2 + 15) >> 4
  1222                                  	cmp cx, dx		; INIT1 code is above intended stack ?
  1223                                  	jae @F			; yes -->
  1224                                  
  1225                                  	lframe
  1226                                  	lenter
  1227                                  	lvar	word, exemode
  1228                                  	 push bx
  1229                                   %if ?exemode != -2
  1230                                    %error exemode variable must be directly below bp
  1231                                   %endif
  1232                                  	mov bx, -1		; unimplemented, return error
  1233                                  	jmp error
  1234                                  	lleave ctx
  1235                                  @@:
  1236                                  	cli
  1237                                  	pop ss			; = relocated ss value
  1238                                  	mov sp, (_IMAGE_EXE_SP + 2) & 0FFFFh	; change stack
  1239                                  	sti
  1240                                  %endif
  1241                                  
  1242 00000027 31C9                    	xor cx, cx
  1243 00000029 51                      	push cx			; put zero on top of stack
  1244                                  
  1245                                  %if _IMAGE_EXE_IP < 256
  1246                                  	mov cl, _IMAGE_EXE_IP
  1247                                  %elif (_IMAGE_EXE_IP & 255) == 0
  1248                                  	mov ch, _IMAGE_EXE_IP >> 8
  1249                                  %else
  1250 0000002A B94001                  	mov cx, _IMAGE_EXE_IP
  1251                                  %endif
  1252                                  
  1253                                  %if _IMAGE_EXE_CS == -16
  1254 0000002D 83C6F0                  	add si, -16
  1255 00000030 8EDE                    	mov ds, si
  1256 00000032 8EC6                    	mov es, si
  1257                                  %else
  1258                                  	lea dx, [si - 10h]	; => PSP
  1259                                  	mov ds, dx
  1260                                  	mov es, dx		; ds = es => PSP
  1261                                   %if _IMAGE_EXE_CS
  1262                                  	add si, _IMAGE_EXE_CS	; = relocated cs value
  1263                                   %endif
  1264                                  %endif
  1265 00000034 56                      	push si
  1266 00000035 51                      	push cx
  1267                                  %if _LCFG && _PASSLCFG
  1268 00000036 BF[B003]                	mov di, transfer_lcfg_block
  1269 00000039 8CC9                    	mov cx, cs
  1270                                  %endif
  1271 0000003B CB                      	retf			; jump to EXE mode of image
  1272                                  
  1273                                  %endif
  1274                                  .jmp_kernel_mode:
  1275                                  %if _LCFG && _PASSLCFG
  1276 0000003C BF[B003]                	mov di, transfer_lcfg_block
  1277 0000003F 8CC9                    	mov cx, cs
  1278                                  %endif
  1279 00000041 EA01006000              	jmp 60h + _EXEC_SEGMENT:_EXEC_OFFSET
  1280                                  
  1281                                  
  1282                                  %if _TEST_PROGRAM
  1283                                  disp_al_counter:
  1284 00000046 2EFF06[4C00]            	inc word [cs:init1_c_mode_counter]	; 5 bytes
  1285 0000004B C3                      	retn					; 1 byte
  1286                                  
  1287 0000004C 0000                    init1_c_mode_counter:		dw 0		; 2 bytes, total 8
  1288                                  %else
  1289                                   %if _PROGRESS
  1290                                  disp_al_counter equ step_progress
  1291                                   %else
  1292                                  disp_al_counter equ disp_al
  1293                                   %endif
  1294                                  %endif
  1295                                  
  1296                                  
  1297                                  error:
  1298                                   %ifn _TEST_PROGRAM		; 2 bytes
  1299                                  	push cs
  1300                                  	pop ds
  1301                                   %endif
  1302                                  %if _DEBUG0
  1303                                  	mov si, msg.error_begin
  1304                                  	call disp_error
  1305                                  	xchg ax, bx			; ax = error code
  1306                                  	call disp_ax_hex
  1307                                   %ifn _TEST_PROGRAM		; 3 bytes
  1308                                  	mov si, msg.error_end
  1309                                   %endif
  1310                                  %else
  1311                                   %ifn _TEST_PROGRAM		; 3 bytes
  1312                                  	mov si, msg.error
  1313                                   %endif
  1314                                  %endif
  1315                                   %ifn _TEST_PROGRAM		; 3 bytes, total 2 + 3 + 3 = 8
  1316                                  	call disp_error
  1317                                   %endif
  1318                                  %if _DEVICE
  1319                                  	test byte [bp - 2], 2
  1320                                  	jz .exit_app_or_kernel
  1321                                  
  1322                                  	pop si				; => device segment
  1323                                  	pop bx				; mode word
  1324                                  	pop bp
  1325                                  	pop ax
  1326                                  	mov es, si
  1327                                  	xor di, di			; -> device header
  1328                                  	 push cs
  1329                                  	 pop ds
  1330                                  	mov si, device_header_copy	; -> to reset header
  1331                                  	mov cx, words(device_header_copy.length)
  1332                                  	rep movsw		; overwrite device header with default
  1333                                  				;  (reset to a valid state after unsuccessful
  1334                                  				;  decompression, which may have partially
  1335                                  				;  written the header already)
  1336                                  	 push es
  1337                                  	 pop ds				; -> device segment
  1338                                  	pop es
  1339                                  	pop bx
  1340                                  	mov word [es:bx + 3], 8103h	; set error, done, invalid command
  1341                                  	mov byte [es:bx + 13], 0	; set number of units = 0
  1342                                  	mov word [es:bx + 14 + 2], ds
  1343                                  	and word [es:bx + 14], 0	; -> after end of memory to allocate
  1344                                  	pop ax
  1345                                  	pop cx
  1346                                  	pop dx
  1347                                  	pop di
  1348                                  	pop si
  1349                                  	pop ds
  1350                                  	pop bp
  1351                                  	add sp, 4		; discard far return to payload's strategy
  1352                                  	retf			; return to DOS
  1353                                  
  1354                                  
  1355                                  .exit_app_or_kernel:
  1356                                  %endif
  1357                                  
  1358                                  %if _IMAGE_EXE
  1359                                  %if _BOOTLDR
  1360 0000004E F646FE01                	test byte [bp - 2], 1
  1361 00000052 7405                    	jz .exit_kernel_mode
  1362                                  %endif
  1363                                  
  1364 00000054 B87F4C                  	mov ax, 4C7Fh
  1365 00000057 CD21                    	int 21h
  1366                                  
  1367                                  .exit_kernel_mode:
  1368                                  %endif
  1369                                  %if _BOOTLDR
  1370 00000059 31C0                    	xor ax, ax
  1371 0000005B CD16                    	int 16h
  1372 0000005D CD19                    	int 19h
  1373                                  %endif
  1374                                  
  1375                                  
  1376                                  %if _PROGRESS
  1377                                  step_progress:
  1378 0000005F F9                      	stc
  1379                                  .CF:
  1380 00000060 53                      	push bx
  1381 00000061 51                      	push cx
  1382 00000062 52                      	push dx
  1383 00000063 1E                      	push ds
  1384 00000064 56                      	push si
  1385 00000065 57                      	push di
  1386 00000066 50                      	push ax
  1387                                  
  1388 00000067 0E                      	push cs
  1389 00000068 1F                      	pop ds
  1390                                  
  1391 00000069 8316[9A01]00            	adc word [.counter], 0
  1392 0000006E A1[9A01]                	mov ax, word [.counter]
  1393                                  
  1394                                   %if _PROGRESSMULTI
  1395                                    %if _IMAGE_EXE || _DEVICE
  1396                                     %assign defaultprogresshandler _PROGRESSDEFAULT
  1397                                    %else
  1398                                     %assign defaultprogresshandler _PROGRESSDEFAULTBOOT
  1399                                    %endif
  1400 00000071 E91600                  	jmp strict near . %+ defaultprogresshandler %+ _step
  1401                                  .handler: equ $ - 2		; SMC, patched to dispatch to handler
  1402                                  .base:
  1403                                   %endif
  1404                                  
  1405                                  .2_step:
  1406 00000074 BAE803                  	mov dx, 1000
  1407 00000077 F7E2                    	mul dx			; dx:ax = counter times 1000
  1408                                  %if _PROGRESSAMOUNT
  1409 00000079 B90100                  	mov cx, _PROGRESSAMOUNT
  1410 0000007C F7F1                    	div cx			; ax = 0..1000
  1411                                  %else
  1412                                   %warning Progress amount is zero
  1413                                  	mov ax, 1
  1414                                  %endif
  1415                                  
  1416                                  %if 0
  1417                                  	cmp word [.display], ax
  1418                                  	je .ret
  1419                                  	mov word [.display], ax
  1420                                  %endif
  1421 0000007E BE[A301]                	mov si, .message_number_end - 1
  1422 00000081 E80E00                  	call .format_percentage
  1423                                  
  1424 00000084 BE[9C01]                	mov si, .message
  1425 00000087 E82A01                  	call disp_error
  1426                                  
  1427                                  .ret:
  1428 0000008A 58                      	pop ax
  1429                                  .ret_ax:
  1430 0000008B 5F                      	pop di
  1431 0000008C 5E                      	pop si
  1432 0000008D 1F                      	pop ds
  1433 0000008E 5A                      	pop dx
  1434 0000008F 59                      	pop cx
  1435 00000090 5B                      	pop bx
  1436                                  .retn:
  1437 00000091 C3                      	retn
  1438                                  
  1439                                  
  1440                                  .format_percentage:
  1441 00000092 BB0200                  	mov bx, 2		; skip dot
  1442                                  
  1443 00000095 B90A00                  	mov cx, 10		; base
  1444                                  @@:
  1445 00000098 31D2                    	xor dx, dx		; dx:ax = current number
  1446 0000009A F7F1                    	div cx			; dl = remainder, ax = next number
  1447 0000009C 80C230                  	add dl, '0'		; make decit
  1448 0000009F 8814                    	mov byte [si], dl	; store
  1449 000000A1 29DE                    	sub si, bx		; -> next digit slot
  1450 000000A3 80FB02                  	cmp bl, 2		; did we just store fractional ?
  1451 000000A6 B301                    	mov bl, 1		; ! next iteration do not skip dot
  1452 000000A8 74EE                    	je @B			; yes, loop always -->
  1453 000000AA 85C0                    	test ax, ax		; nonzero left ?
  1454 000000AC 75EA                    	jnz @B			; yes, loop if so -->
  1455 000000AE C3                      	retn
  1456                                  
  1457                                  
  1458                                   %if _PROGRESSMULTI
  1459                                  .0_step: equ .ret
  1460                                  
  1461                                  .1_step:
  1462 000000AF 58                      	pop ax
  1463 000000B0 E80F01                  	call disp_al
  1464 000000B3 EBD6                    	jmp .ret_ax
  1465                                  
  1466                                  .3_step:
  1467 000000B5 BB4B00                  	mov bx, 80 - 1 - 4
  1468 000000B8 F7E3                    	mul bx			; dx:ax = counter times 75
  1469                                  %if _PROGRESSAMOUNT
  1470 000000BA B90100                  	mov cx, _PROGRESSAMOUNT
  1471 000000BD F7F1                    	div cx			; ax = 0..75
  1472                                  %else
  1473                                   %warning Progress amount is zero
  1474                                  	mov ax, 1
  1475                                  %endif
  1476                                  
  1477 000000BF 3906[9801]              	cmp word [.display], ax
  1478 000000C3 74C5                    	je .ret
  1479 000000C5 A3[9801]                	mov word [.display], ax
  1480                                  
  1481 000000C8 50                      	push ax
  1482 000000C9 91                      	xchg cx, ax
  1483 000000CA B00D                    	mov al, 13
  1484 000000CC E8F300                  	call disp_al
  1485 000000CF B05B                    	mov al, '['
  1486 000000D1 E8EE00                  	call disp_al
  1487 000000D4 B020                    	mov al, 32
  1488 000000D6 E8E900                  	call disp_al
  1489                                  
  1490 000000D9 B023                    	mov al, '#'
  1491 000000DB E305                    	jcxz @FF
  1492                                  @@:
  1493 000000DD E8E200                  	call disp_al
  1494 000000E0 E2FB                    	loop @B
  1495                                  @@:
  1496                                  
  1497 000000E2 B020                    	mov al, 32
  1498 000000E4 59                      	pop cx
  1499 000000E5 29CB                    	sub bx, cx
  1500 000000E7 7607                    	jbe @FF
  1501 000000E9 89D9                    	mov cx, bx
  1502                                  @@:
  1503 000000EB E8D400                  	call disp_al
  1504 000000EE E2FB                    	loop @B
  1505                                  @@:
  1506                                  
  1507                                  .m4done:
  1508 000000F0 E8CF00                  	call disp_al
  1509 000000F3 B05D                    	mov al, ']'
  1510 000000F5 E8CA00                  	call disp_al
  1511 000000F8 EB90                    	jmp .ret
  1512                                  
  1513                                  
  1514                                  .4_step:
  1515 000000FA 50                      	push ax
  1516                                  
  1517 000000FB BAE803                  	mov dx, 1000
  1518 000000FE F7E2                    	mul dx			; dx:ax = counter times 1000
  1519                                  %if _PROGRESSAMOUNT
  1520 00000100 B90100                  	mov cx, _PROGRESSAMOUNT
  1521 00000103 F7F1                    	div cx			; ax = 0..1000
  1522                                  %else
  1523                                   %warning Progress amount is zero
  1524                                  	mov ax, 1
  1525                                  %endif
  1526                                  
  1527 00000105 BE[AD01]                	mov si, .message_4_number_end - 1
  1528 00000108 E887FF                  	call .format_percentage
  1529                                  
  1530 0000010B 58                      	pop ax
  1531 0000010C BB4B00                  	mov bx, 80 - 1 - 4
  1532 0000010F F7E3                    	mul bx			; dx:ax = counter times 75
  1533                                  %if _PROGRESSAMOUNT
  1534 00000111 B90100                  	mov cx, _PROGRESSAMOUNT
  1535 00000114 F7F1                    	div cx			; ax = 0..75
  1536                                  %else
  1537                                   %warning Progress amount is zero
  1538                                  	mov ax, 1
  1539                                  %endif
  1540                                  
  1541 00000116 50                      	push ax
  1542 00000117 91                      	xchg cx, ax
  1543 00000118 B00D                    	mov al, 13
  1544 0000011A E8A500                  	call disp_al
  1545 0000011D B05B                    	mov al, '['
  1546 0000011F E8A000                  	call disp_al
  1547 00000122 B020                    	mov al, 32
  1548 00000124 E89B00                  	call disp_al
  1549                                  
  1550 00000127 31FF                    	xor di, di
  1551 00000129 BA2200                  	mov dx, (80 - 1 - 4 - .message_4_length) / 2
  1552 0000012C 803E[A901]20            	cmp byte [.message_4_number], 32
  1553 00000131 7401                    	je @F
  1554 00000133 47                      	inc di
  1555                                  @@:
  1556 00000134 29FA                    	sub dx, di
  1557                                  
  1558 00000136 B023                    	mov al, '#'
  1559 00000138 E306                    	jcxz @FF
  1560                                  @@:
  1561 0000013A E88500                  	call disp_al
  1562 0000013D 4A                      	dec dx
  1563 0000013E E0FA                    	loopnz @B
  1564                                  @@:
  1565                                  
  1566 00000140 85D2                    	test dx, dx
  1567 00000142 752E                    	jnz .notyetm4
  1568                                  
  1569 00000144 BE[A901]                	mov si, .message_4
  1570 00000147 29FE                    	sub si, di
  1571 00000149 E86800                  	call disp_error
  1572                                  
  1573 0000014C 29F9                    	sub cx, di
  1574 0000014E 760E                    	jbe @FF
  1575 00000150 83E907                  	sub cx, .message_4_length
  1576 00000153 7609                    	jbe @FF
  1577 00000155 89CA                    	mov dx, cx
  1578 00000157 B023                    	mov al, '#'
  1579                                  @@:
  1580 00000159 E86600                  	call disp_al
  1581 0000015C E2FB                    	loop @B
  1582                                  @@:
  1583 0000015E 59                      	pop cx
  1584 0000015F B020                    	mov al, 32
  1585 00000161 83EB29                  	sub bx, (80 - 1 - 4 - .message_4_length) / 2 + .message_4_length
  1586 00000164 29D3                    	sub bx, dx
  1587 00000166 7607                    	jbe @FF
  1588 00000168 89D9                    	mov cx, bx
  1589                                  @@:
  1590 0000016A E85500                  	call disp_al
  1591 0000016D E2FB                    	loop @B
  1592                                  @@:
  1593 0000016F E97EFF                  	jmp .m4done
  1594                                  
  1595                                  .notyetm4:
  1596 00000172 B020                    	mov al, 32
  1597 00000174 59                      	pop cx
  1598 00000175 29CB                    	sub bx, cx
  1599 00000177 7608                    	jbe @FF
  1600 00000179 89D9                    	mov cx, bx
  1601                                  @@:
  1602 0000017B E84400                  	call disp_al
  1603 0000017E 4A                      	dec dx
  1604 0000017F E0FA                    	loopnz @B
  1605                                  @@:
  1606                                  
  1607 00000181 BE[A901]                	mov si, .message_4
  1608 00000184 29FE                    	sub si, di
  1609 00000186 E82B00                  	call disp_error
  1610                                  
  1611 00000189 B020                    	mov al, 32
  1612 0000018B 29F9                    	sub cx, di
  1613 0000018D 83E907                  	sub cx, .message_4_length
  1614                                  	; jbe @FF
  1615                                  @@:
  1616 00000190 E82F00                  	call disp_al
  1617 00000193 E2FB                    	loop @B
  1618                                  @@:
  1619 00000195 E958FF                  	jmp .m4done
  1620                                  %endif
  1621                                  
  1622                                  	align 2, db 0
  1623                                   %if _PROGRESSMULTI
  1624 00000198 FFFF                    .display:	dw -1
  1625                                   %endif
  1626 0000019A 0000                    .counter:	dw 0
  1627 0000019C 0D5B20                  .message:	db 13,"[ "
  1628 0000019F 2020312E30              .message_number:db "  1.0"	; enough digit slots for 100.0%,
  1629                                  				;  blanks are pre-init until written
  1630                                  .message_number_end:
  1631 000001A4 25205D00                		db "% ]",0
  1632                                   %if _PROGRESSMULTI
  1633 000001A8 20                      		db " "
  1634                                  .message_4:
  1635 000001A9 2020312E30              .message_4_number:db "  1.0"	; enough digit slots for 100.0%,
  1636                                  				;  blanks are pre-init until written
  1637                                  .message_4_number_end:
  1638 000001AE 252000                  		db "% ",0
  1639                                  .message_4_length: equ $ - 1 - .message_4
  1640                                   %endif
  1641                                  %endif
  1642                                  
  1643                                  
  1644                                  %if _DEVICE
  1645                                  	align 16
  1646                                  device_header_copy:
  1647                                  .:
  1648                                  .next:
  1649                                  	dd -1				; already initialised
  1650                                  .attributes:
  1651                                  	dw _DEVICE_ATTRIBUTE
  1652                                  .strategy:
  1653                                  	dw .strategy_entry - .		; -> strategy entry
  1654                                  .interrupt:
  1655                                  	dw .interrupt_entry - .		; -> interrupt entry
  1656                                  .name:
  1657                                  	fill 8, 32, db _DEVICE_NAME
  1658                                  
  1659                                  .strategy_entry:
  1660                                  	fill 4, 90h, jmp .set_error	; rel8 or rel16 jump, not minus .
  1661                                  .interrupt_entry:
  1662                                  	fill 4, 90h, retf
  1663                                  
  1664                                  .set_error:
  1665                                  	mov word [es:bx + 3], 8103h	; set error, done, invalid command
  1666                                  	retf
  1667                                  .length: equ $ - .
  1668                                  %endif
  1669                                  
  1670                                  
  1671                                  disp_error.loop:
  1672 000001B1 E80E00                  	call disp_al
  1673                                  disp_error:
  1674 000001B4 AC                      	lodsb
  1675 000001B5 84C0                    	test al, al
  1676 000001B7 75F8                    	jnz .loop
  1677 000001B9 C3                      	retn
  1678                                  
  1679                                  %if _DEBUG0 || _DEBUG1 || _DEBUG2 || _DEBUG3
  1680                                  disp_ax_hex:			; ax
  1681                                  		xchg al,ah
  1682                                  		call disp_al_hex		; display former ah
  1683                                  		xchg al,ah			;  and fall trough for al
  1684                                  disp_al_hex:			; al
  1685                                  		push cx
  1686                                  		mov cl,4
  1687                                  		ror al,cl
  1688                                  		call disp_al_lownibble_hex	; display former high-nibble
  1689                                  		rol al,cl
  1690                                  		pop cx
  1691                                  						;  and fall trough for low-nibble
  1692                                  disp_al_lownibble_hex:
  1693                                  		push ax			 ; save ax for call return
  1694                                  		and al,00001111b		; high nibble must be zero
  1695                                  		add al,'0'			; if number is 0-9, now it's the correct character
  1696                                  		cmp al,'9'
  1697                                  		jna .decimalnum		 ; if we get decimal number with this, ok -->
  1698                                  		add al,7			;  otherwise, add 7 and we are inside our alphabet
  1699                                   .decimalnum:
  1700                                  		call disp_al
  1701                                  		pop ax
  1702                                  		retn
  1703                                  %endif
  1704                                  
  1705                                  
  1706                                  disp_al_for_progress:
  1707                                  %if _PROGRESS && _PROGRESSMULTI
  1708 000001BA 2E833E[7200]16          	cmp word [cs:step_progress.handler], step_progress.0_step - step_progress.base
  1709 000001C0 741B                    	je disp_al.retn
  1710                                  %endif
  1711                                  disp_al:
  1712                                  %if _TEST_PROGRAM
  1713 000001C2 C3                      	retn
  1714                                  %else
  1715                                  	push ax
  1716                                  %endif
  1717                                  %if _BOOTLDR
  1718 000001C3 53                      	push bx
  1719 000001C4 55                      	push bp
  1720 000001C5 B40E                    	mov ah, 0Eh
  1721 000001C7 BB0700                  	mov bx, 7
  1722                                  %endif
  1723                                  %if _IMAGE_EXE || _DEVICE
  1724 000001CA 52                      	push dx
  1725                                  
  1726                                  %if _BOOTLDR
  1727 000001CB F646FE03                	test byte [bp - 2], 1 | 2
  1728 000001CF 7406                    	jz .display_kernel_mode
  1729                                  %endif
  1730                                  
  1731 000001D1 92                      	xchg dx, ax				; dl = input al
  1732 000001D2 B402                    	mov ah, 02h
  1733 000001D4 CD21                    	int 21h
  1734                                  %if _BOOTLDR
  1735 000001D6 A9                      	db __TEST_IMM16				; (skip int)
  1736                                  %endif
  1737                                  
  1738                                  .display_kernel_mode:
  1739                                  %endif
  1740                                  %if _BOOTLDR
  1741 000001D7 CD10                    	int 10h
  1742                                  %endif
  1743                                  %if _IMAGE_EXE
  1744 000001D9 5A                      	pop dx
  1745                                  %endif
  1746                                  %if _BOOTLDR
  1747 000001DA 5D                      	pop bp
  1748 000001DB 5B                      	pop bx
  1749                                  %endif
  1750 000001DC 58                      	pop ax
  1751                                  .retn:
  1752                                  disp_error.ret:
  1753 000001DD C3                      	retn
  1754                                  
  1755                                  
  1756                                  msg:
  1757                                  %if _DEBUG0
  1758                                  .error_begin:	db "Load error: Decompression failure, code ",0
  1759                                  .error_end:	db "h.",13,10,0
  1760                                  %else
  1761 000001DE 4C6F6164206572726F-     .error:		db "Load error: Decompression failure.",13,10,0
  1761 000001E7 723A204465636F6D70-
  1761 000001F0 72657373696F6E2066-
  1761 000001F9 61696C7572652E0D0A-
  1761 00000202 00                 
  1762                                  %endif
  1763                                  
  1764                                  
  1765                                  %assign NEED_NORMALISE_POINTER_WITH_DISPLACEMENT 1
  1766                                  %assign NEED_NORMALISE_BOTH_POINTERS 1
  1767                                  %assign CHECK_POINTERS_VARIABLE_SRC 1
  1768                                  %assign CHECK_POINTERS_VARIABLE_DST 1
  1769                                  
  1770                                  		; Specific depacker's file is included within label msg.
  1771                                  		; In the file, lframe is used and lleave ctx is not used.
  1772                                  
  1773                                  %if _BRIEFLZ
  1774                                  	%include "brieflz.asm"
  1775                                  %endif
  1776                                  
  1777                                  
  1778                                  %if _LZ4
  1779                                  	%include "lz4.asm"
  1780                                  %endif
  1781                                  
  1782                                  
  1783                                  %if _SNAPPY
  1784                                  	%include "snappy.asm"
  1785                                  %endif
  1786                                  
  1787                                  
  1788                                  %if _EXODECR
  1789                                  	%include "exodecr.asm"
  1790                                  %endif
  1791                                  
  1792                                  
  1793                                  %if _X
  1794                                  	%include "x.asm"
  1795                                  %endif
  1796                                  
  1797                                  
  1798                                  %if _HEATSHRINK
  1799                                  	%include "heatshr.asm"
  1800                                  %endif
  1801                                  
  1802                                  
  1803                                  %if _LZD
  1804                                  	%include "lzd.asm"
  1805                                  %endif
  1806                                  
  1807                                  
  1808                                  %if _LZO
  1809                                  	%include "lzo.asm"
  1810                                  %endif
  1811                                  
  1812                                  
  1813                                  %if _LZSA2
  1814                                  	%include "lzsa2.asm"
  1815                                  %endif
  1816                                  
  1817                                  
  1818                                  %if _APL
  1819                                  	%include "apl.asm"
  1820                                  %endif
  1821                                  
  1822                                  
  1823                                  %if _BZP
  1824                                  	%include "bzp.asm"
  1825                                  %endif
  1826                                  
  1827                                  
  1828                                  %if _ZEROCOMP
  1829                                  	%include "zerocomp.asm"
  1830                                  %endif
  1831                                  
  1832                                  
  1833                                  %if _MVCOMP
  1834                                  	%include "mvcomp.asm"
  1835                                  %endif
  1836                                  
  1837                                  
  1838                                  %if _LZEXEDAT
  1839                                  	%include "lzexedat.asm"
     1                              <1> 
     2                              <1> %if 0
     3                              <1> 
     4                              <1> 8086 Assembly lDOS iniload payload LZEXE depacker
     5                              <1>  by E. C. Masloch, 2020--2025
     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> 
    16                              <1> 	numdef TESTFILE,	0
    17                              <1> 	numdef 4,		0
    18                              <1> 	numdef LONGLITERAL,	0
    19                              <1> %assign NEED_NORMALISE_POINTER_WITH_DISPLACEMENT 0
    20                              <1> %assign NEED_NORMALISE_BOTH_POINTERS 0
    21                              <1> %assign CHECK_POINTERS_VARIABLE_SRC 0
    22                              <1> %assign CHECK_POINTERS_VARIABLE_DST 0
    23                              <1> 
    24                              <1> 
    25                              <1> %if _TESTFILE
    26                              <1> .verbose.2:	db @F - ($ + 1)
    27                              <1> 		db "dest="
    28                              <1> .verbose.2.desthigh:
    29                              <1> 		db "----_"
    30                              <1> .verbose.2.destlow:
    31                              <1> 		db "----h src="
    32                              <1> .verbose.2.srchigh:
    33                              <1> 		db "----_"
    34                              <1> .verbose.2.srclow:
    35                              <1> 		db "----h "
    36                              <1> 		db "Match -"
    37                              <1> .verbose.2.index:
    38                              <1> 		db "----h length "
    39                              <1> .verbose.2.length:
    40                              <1> 		db "----h masque="
    41                              <1> .verbose.2.masque:
    42                              <1> 		db "----h left="
    43                              <1> .verbose.2.left:
    44                              <1> 		db "--h.",13,10
    45                              <1> @@:
    46                              <1> .except.2:	db @F - ($ + 1)
    47                              <1> 		db "dest="
    48                              <1> .except.2.desthigh:
    49                              <1> 		db "----_"
    50                              <1> .except.2.destlow:
    51                              <1> 		db "----h src="
    52                              <1> .except.2.srchigh:
    53                              <1> 		db "----_"
    54                              <1> .except.2.srclow:
    55                              <1> 		db "----h "
    56                              <1> 		db "Literal length "
    57                              <1> .except.2.lengthhigh:
    58                              <1> 		db "----_"
    59                              <1> .except.2.lengthlow:
    60                              <1> 		db "----h masque="
    61                              <1> .except.2.masque:
    62                              <1> 		db "----h left="
    63                              <1> .except.2.left:
    64                              <1> 		db "--h.",13,10
    65                              <1> @@:
    66                              <1> .extra.2:	db @F - ($ + 1)
    67                              <1> 		db "dest="
    68                              <1> .extra.2.desthigh:
    69                              <1> 		db "----_"
    70                              <1> .extra.2.destlow:
    71                              <1> 		db "----h src="
    72                              <1> .extra.2.srchigh:
    73                              <1> 		db "----_"
    74                              <1> .extra.2.srclow:
    75                              <1> 		db "----h "
    76                              <1> 		db "Literal reads "
    77                              <1> .extra.2.value:
    78                              <1> 		db "--h '"
    79                              <1> .extra.2.text:
    80                              <1> 		db "-' masque="
    81                              <1> .extra.2.masque:
    82                              <1> 		db "----h left="
    83                              <1> .extra.2.left:
    84                              <1> 		db "--h.",13,10
    85                              <1> @@:
    86                              <1> .extra.3:	db @F - ($ + 1)
    87                              <1> 		db " command "
    88                              <1> 		db "dest="
    89                              <1> .extra.3.desthigh:
    90                              <1> 		db "----_"
    91                              <1> .extra.3.destlow:
    92                              <1> 		db "----h src="
    93                              <1> .extra.3.srchigh:
    94                              <1> 		db "----_"
    95                              <1> .extra.3.srclow:
    96                              <1> 		db "----h masque="
    97                              <1> .extra.3.masque:
    98                              <1> 		db "----h left="
    99                              <1> .extra.3.left:
   100                              <1> 		db "--h.",13,10
   101                              <1> @@:
   102                              <1> .extra.4.eos:	counted "EOS"
   103                              <1> .extra.4.segchange:
   104                              <1> 		counted "Seg Change"
   105                              <1> .extra.4.longliteral:
   106                              <1> 		counted "Long Literal"
   107                              <1> 
   108                              <1> 	align 2, db 0
   109                              <1> literalamount:	dd 0
   110                              <1> %endif
   111                              <1> 
   112                              <1> 
   113                              <1> 	numdef COUNTER,		0, 64
   114                              <1> %if (_COUNTER - 1) & _COUNTER
   115                              <1>  %error COUNTER must be a power of two
   116                              <1> %endif
   117                              <1> 
   118                              <1> 
   119                              <1> 		; INP:	ds:si -> source
   120                              <1> 		;	dx:cx = length of source
   121                              <1> 		;	es:di -> destination (below source)
   122                              <1> 		;	if _IMAGE_EXE:
   123                              <1> 		;	 bx = EXE mode flag (bit 0)
   124                              <1> 		;	else:
   125                              <1> 		;	 bx = 0
   126                              <1> 		;	if _PAYLOAD_KERNEL_MAX_PARAS:
   127                              <1> 		;	 ax = maximum amount in paragraphs of destination needed
   128                              <1> 		;	 (-1 if full source should be decompressed)
   129                              <1> 		;	else:
   130                              <1> 		;	 ax = -1
   131                              <1> 		; OUT:	NC if success
   132                              <1> 		;	CY if error,
   133                              <1> 		;	 bx = ?errordata (if _DEBUG0)
   134                              <1> 		; CHG:	ax, (bx), cx, dx, es, ds, si, di
   135                              <1> 		; STT:	UP
   136                              <1> 		;
   137                              <1> 		; Note:	The destination reaches up to below the source.
   138                              <1> 		; Note:	The input pointers need to be normalised.
   139                              <1> 		;	 Normalised means that the offset part is below 16.
   140                              <1> depack:
   141                              <1> 	lframe near
   142 00000203 5589E5              <1> 	lenter
   143                              <1>  %if _IMAGE_EXE
   144                              <1> 	lvar word,	exemode	; must be bp - 2!
   145 00000206 53                  <1> 	 push bx
   146                              <1>   %if ?exemode != -2
   147                              <1>    %error exemode variable must be directly below bp
   148                              <1>   %endif
   149                              <1>  %endif
   150                              <1>  %if _DEBUG0 || _COUNTER
   151 00000207 31DB                <1> 	xor bx, bx
   152                              <1>  %endif
   153                              <1>  %if _DEBUG0
   154                              <1> 	lvar word,	errordata
   155                              <1> 	 push bx
   156                              <1>  %endif
   157                              <1> %if _COUNTER
   158                              <1> 	lvar word,	unused_and_counter
   159                              <1> 	lequ ?unused_and_counter + 1, counter
   160 00000209 53                  <1> 	 push bx		; initialise counter (high byte) to zero
   161                              <1> %endif
   162                              <1> 
   163                              <1> %if _TESTFILE
   164                              <1> 	lvar dword,	original_src
   165                              <1> 	 push ds
   166                              <1> 	 push si
   167                              <1> 	lvar dword,	original_dst
   168                              <1> 	 push es
   169                              <1> 	 push di
   170                              <1> %endif
   171                              <1> 	lvar dword,	src_remaining
   172 0000020A 52                  <1> 	 push dx
   173 0000020B 51                  <1> 	 push cx
   174                              <1> 
   175                              <1> %if 0 && _PAYLOAD_KERNEL_MAX_PARAS
   176                              <1> 	cmp ax, -1		; no maximum specified ?
   177                              <1> 	je @FF			; retain -1 in ax -->
   178                              <1> 	test di, di		; do we need an additional paragraph ?
   179                              <1> 	jz @F			; no -->
   180                              <1> 	inc ax			; es + ax => paragraph after necessary part
   181                              <1> @@:
   182                              <1> 	mov dx, es
   183                              <1> 	add ax, dx		; => paragraph after necessary part
   184                              <1> 		; If the normalised destination pointer's segment grows
   185                              <1> 		;  to this segment then enough has been decompressed.
   186                              <1> d0	mov byte [bp + ?errordata], 7Fh
   187                              <1> 	jc .error		; should not carry
   188                              <1> @@:
   189                              <1> 	lvar word,	dst_max_segment
   190                              <1> 	 push ax
   191                              <1> %endif
   192                              <1> 
   193 0000020C 1E                  <1> 	 push ds
   194 0000020D 56                  <1> 	 push si
   195 0000020E E87C01              <1> 	call pointer_to_linear
   196                              <1> 
   197 00000211 89D3                <1> 	mov bx, dx
   198 00000213 91                  <1> 	xchg cx, ax		; bx:cx = source linear
   199                              <1> 
   200 00000214 06                  <1> 	 push es
   201 00000215 57                  <1> 	 push di
   202 00000216 E87401              <1> 	call pointer_to_linear
   203                              <1> 
   204                              <1> %if _ALLOW_OVERLAPPING
   205 00000219 034EF8              <1> 	add cx, word [bp + ?src_remaining]
   206 0000021C 135EFA              <1> 	adc bx, word [bp + ?src_remaining + 2]
   207                              <1> 		; In case of allowing overlapping source and destination,
   208                              <1> 		;  the ?dst_remaining variable is set to
   209                              <1> 		;  ?src + ?src_remaining - ?dst, allowing to write to
   210                              <1> 		;  all of the source buffer (with the checks already in place
   211                              <1> 		;  from the default handling). Additional checks are done by
   212                              <1> 		;  calling check_pointers_not_overlapping. This is done after
   213                              <1> 		;  every change of ?dst to verify that the write pointer stays
   214                              <1> 		;  below-or-equal the read pointer.
   215                              <1> 		; This means the remaining source data may be corrupted by a
   216                              <1> 		;  write, but nothing after the source data is written to,
   217                              <1> 		;  so the error handling (in INIT1 after the data) still works.
   218                              <1> %endif
   219                              <1> 
   220 0000021F 29C1                <1> 	sub cx, ax
   221 00000221 19D3                <1> 	sbb bx, dx		; bx:cx = source linear - destination linear
   222                              <1> 
   223                              <1> 	lvar dword,	dst_remaining
   224 00000223 53                  <1> 	 push bx		; push into [bp + ?dst_remaining + 2]
   225 00000224 51                  <1> 	 push cx		; push into [bp + ?dst_remaining]
   226                              <1> 
   227                              <1> %if _ALLOW_OVERLAPPING
   228 00000225 E81901              <1> 	call check_pointers_not_overlapping
   229                              <1> 		; Note:	We initially check here that the write pointer is
   230                              <1> 		;	 low enough, ie below-or-equal the read pointer.
   231                              <1> 		;	 Doing this check here (as well as after any
   232                              <1> 		;	 copied match) allows us to drop the check done
   233                              <1> 		;	 after moving literal bytes.
   234                              <1> d0	mov byte [bp + ?errordata], 7Eh
   235 00000228 7303E9D400          <1> 	jc .error
   236                              <1> %endif
   237                              <1> 
   238                              <1> 	lvar word,	tagword
   239 0000022D 50                  <1> 	 push ax
   240 0000022E B80100              <1> 	mov ax, 1
   241                              <1> 	lvar word,	tagbitscycle
   242 00000231 50                  <1> 	 push ax		; = 1
   243                              <1> 
   244 00000232 E8DD00              <1> 	call get_bit
   245                              <1> 
   246 00000235 EB26                <1> 	jmp .loop
   247                              <1> 
   248                              <1> .literal:
   249                              <1> %if _LONGLITERAL
   250 00000237 41                  <1> 	inc cx
   251                              <1> .loop_literal:
   252                              <1> %endif
   253                              <1> 
   254                              <1> %if _TESTFILE
   255                              <1> 	add word [ss:literalamount], 1
   256                              <1> 	adc word [ss:literalamount + 2], 0
   257                              <1> %endif
   258 00000238 836EF801            <1> 	sub word [bp + ?src_remaining], 1
   259 0000023C E8F000              <1> 	call sbb_src_remaining_check
   260 0000023F 836EF401            <1> 	sub word [bp + ?dst_remaining], 1
   261 00000243 835EF600            <1> 	sbb word [bp + ?dst_remaining + 2], 0
   262                              <1> d0	mov byte [bp + ?errordata], 70h
   263 00000247 7303E9B500          <1> 	jc .error
   264                              <1> 
   265                              <1> %if _TESTFILE
   266                              <1> 	rol byte [ss:extraverbose], 1
   267                              <1> 	jnc @F
   268                              <1> 	push es
   269                              <1> 	push ds
   270                              <1> 	push ax
   271                              <1> 	push bx
   272                              <1> 	push cx
   273                              <1> 	push dx
   274                              <1> 	push di
   275                              <1> 
   276                              <1> 	mov al, [si]
   277                              <1> 	 push ds
   278                              <1> 	 push si
   279                              <1> 	 push es
   280                              <1> 	 push di
   281                              <1> 	push ss
   282                              <1> 	pop es
   283                              <1> 	mov di, msg.extra.2.value
   284                              <1> 	call store_hex_byte
   285                              <1> 
   286                              <1> 	mov di, msg.extra.2.text
   287                              <1> 	inc ax
   288                              <1> 	cmp al, 32
   289                              <1> 	jg .gottext
   290                              <1> 	mov al, '.' + 1
   291                              <1> .gottext:
   292                              <1> 	dec ax
   293                              <1> 	stosb
   294                              <1> 
   295                              <1> 	mov ax, word [bp + ?tagword]
   296                              <1> 	mov di, msg.extra.2.masque
   297                              <1> 	call store_hex_word
   298                              <1> 
   299                              <1> 	call get_tagbitsleft
   300                              <1> 	mov di, msg.extra.2.left
   301                              <1> 	call store_hex_byte
   302                              <1> 
   303                              <1> 	 push word [bp + ?original_dst + 2]
   304                              <1> 	 push word [bp + ?original_dst]
   305                              <1> 	call pointer_to_linear
   306                              <1> 
   307                              <1> 	xchg cx, ax
   308                              <1> 	xchg bx, dx
   309                              <1> 
   310                              <1> 	 ; es:di on stack
   311                              <1> 	call pointer_to_linear
   312                              <1> 
   313                              <1> 	sub ax, cx
   314                              <1> 	sbb dx, bx
   315                              <1> 
   316                              <1> 	mov di, msg.extra.2.destlow
   317                              <1> 	call store_hex_word
   318                              <1> 	xchg ax, dx
   319                              <1> 	mov di, msg.extra.2.desthigh
   320                              <1> 	call store_hex_word
   321                              <1> 
   322                              <1> 	 push word [bp + ?original_src + 2]
   323                              <1> 	 push word [bp + ?original_src]
   324                              <1> 	call pointer_to_linear
   325                              <1> 
   326                              <1> 	xchg cx, ax
   327                              <1> 	xchg bx, dx
   328                              <1> 
   329                              <1> 	 ; ds:si on stack
   330                              <1> 	call pointer_to_linear
   331                              <1> 
   332                              <1> 	sub ax, cx
   333                              <1> 	sbb dx, bx
   334                              <1> 
   335                              <1> 	mov di, msg.extra.2.srclow
   336                              <1> 	call store_hex_word
   337                              <1> 	xchg ax, dx
   338                              <1> 	mov di, msg.extra.2.srchigh
   339                              <1> 	call store_hex_word
   340                              <1> 
   341                              <1> 	push ss
   342                              <1> 	pop ds
   343                              <1> 	mov dx, msg.extra.2
   344                              <1> 	call disp_msg_counted
   345                              <1> 
   346                              <1> 	pop di
   347                              <1> 	pop dx
   348                              <1> 	pop cx
   349                              <1> 	pop bx
   350                              <1> 	pop ax
   351                              <1> 	pop ds
   352                              <1> 	pop es
   353                              <1> @@:
   354                              <1> %endif
   355                              <1> 
   356 0000024C A4                  <1> 	movsb
   357 0000024D 85F6                <1> 	test si, si			; overflowed ?
   358                              <1> d0	mov byte [bp + ?errordata], 88h
   359 0000024F 7503E9AD00          <1> 	jz .error
   360 00000254 85FF                <1> 	test di, di			; overflowed ?
   361                              <1> d0	mov byte [bp + ?errordata], 89h
   362 00000256 7503E9A600          <1> 	jz .error
   363                              <1> 
   364                              <1> %if _LONGLITERAL
   365                              <1>  %if _TESTFILE
   366                              <1> 	loop .loop_literal_j
   367                              <1> 	jmp .loop
   368                              <1> .loop_literal_j:
   369                              <1> 	jmp .loop_literal
   370                              <1>  %else
   371 0000025B E2DB                <1> 	loop .loop_literal
   372                              <1>  %endif
   373                              <1> %endif
   374                              <1> 
   375                              <1> .loop:
   376 0000025D 31C9                <1> 	xor cx, cx			; ! ch = 0, cx = 0
   377 0000025F E8B000              <1> 	call get_bit
   378 00000262 72D3                <1> 	jc .literal
   379                              <1> 
   380                              <1> %if _TESTFILE
   381                              <1> 	rol byte [ss:exceptional], 1
   382                              <1> 	jnc @F
   383                              <1> 	cmp word [ss:literalamount + 2], 0
   384                              <1> 	jne .high
   385                              <1> 	cmp word [ss:literalamount], 26
   386                              <1> .high:
   387                              <1> 	jb @F
   388                              <1> 	push es
   389                              <1> 	push ds
   390                              <1> 	push ax
   391                              <1> 	push bx
   392                              <1> 	push cx
   393                              <1> 	push dx
   394                              <1> 	push di
   395                              <1> 
   396                              <1> 	 push ds
   397                              <1> 	 push si
   398                              <1> 	 push es
   399                              <1> 	 push di
   400                              <1> 	push ss
   401                              <1> 	pop es
   402                              <1> 	mov ax, word [ss:literalamount]
   403                              <1> 	mov di, msg.except.2.lengthlow
   404                              <1> 	call store_hex_word
   405                              <1> 	mov ax, word [ss:literalamount + 2]
   406                              <1> 	mov di, msg.except.2.lengthhigh
   407                              <1> 	call store_hex_word
   408                              <1> 
   409                              <1> 	mov ax, word [bp + ?tagword]
   410                              <1> 	mov di, msg.except.2.masque
   411                              <1> 	call store_hex_word
   412                              <1> 
   413                              <1> 	call get_tagbitsleft
   414                              <1> 	mov di, msg.except.2.left
   415                              <1> 	call store_hex_byte
   416                              <1> 
   417                              <1> 	 push word [bp + ?original_dst + 2]
   418                              <1> 	 push word [bp + ?original_dst]
   419                              <1> 	call pointer_to_linear
   420                              <1> 
   421                              <1> 	xchg cx, ax
   422                              <1> 	xchg bx, dx
   423                              <1> 
   424                              <1> 	 ; es:di on stack
   425                              <1> 	call pointer_to_linear
   426                              <1> 
   427                              <1> 	sub ax, cx
   428                              <1> 	sbb dx, bx
   429                              <1> 
   430                              <1> 	mov di, msg.except.2.destlow
   431                              <1> 	call store_hex_word
   432                              <1> 	xchg ax, dx
   433                              <1> 	mov di, msg.except.2.desthigh
   434                              <1> 	call store_hex_word
   435                              <1> 
   436                              <1> 	 push word [bp + ?original_src + 2]
   437                              <1> 	 push word [bp + ?original_src]
   438                              <1> 	call pointer_to_linear
   439                              <1> 
   440                              <1> 	xchg cx, ax
   441                              <1> 	xchg bx, dx
   442                              <1> 
   443                              <1> 	 ; ds:si on stack
   444                              <1> 	call pointer_to_linear
   445                              <1> 
   446                              <1> 	sub ax, cx
   447                              <1> 	sbb dx, bx
   448                              <1> 
   449                              <1> 	mov di, msg.except.2.srclow
   450                              <1> 	call store_hex_word
   451                              <1> 	xchg ax, dx
   452                              <1> 	mov di, msg.except.2.srchigh
   453                              <1> 	call store_hex_word
   454                              <1> 
   455                              <1> 	push ss
   456                              <1> 	pop ds
   457                              <1> 	mov dx, msg.except.2
   458                              <1> 	call disp_msg_counted
   459                              <1> 
   460                              <1> 	pop di
   461                              <1> 	pop dx
   462                              <1> 	pop cx
   463                              <1> 	pop bx
   464                              <1> 	pop ax
   465                              <1> 	pop ds
   466                              <1> 	pop es
   467                              <1> @@:
   468                              <1> 	and word [ss:literalamount + 2], 0
   469                              <1> 	and word [ss:literalamount], 0
   470                              <1> %endif
   471                              <1> 
   472                              <1> 
   473                              <1> .notliteral:
   474                              <1> %if _COUNTER
   475 00000264 FE46FD              <1> 	inc byte [bp + ?counter]
   476 00000267 F646FD3F            <1> 	test byte [bp + ?counter], _COUNTER - 1
   477 0000026B 7505                <1> 	jnz @F
   478 0000026D B02E                <1> 	mov al, '.'
   479 0000026F E8D4FD              <1> 	call disp_al_counter
   480                              <1> @@:
   481                              <1> %endif
   482                              <1> 
   483 00000272 E89D00              <1> 	call get_bit
   484 00000275 7234                <1> 	jc .combined
   485                              <1> 
   486                              <1> .shortmatch:
   487                              <1> 		; cx = 0
   488 00000277 E89800              <1> 	call get_bit
   489 0000027A D1D1                <1> 	rcl cx, 1
   490 0000027C E89300              <1> 	call get_bit
   491 0000027F D1D1                <1> 	rcl cx, 1			; cx = 0..3
   492                              <1> 
   493 00000281 E8B200              <1> 	call load_byte			; load displacement
   494                              <1> 
   495 00000284 B4FF                <1> 	mov ah, -1			; sign extend for negative number
   496 00000286 93                  <1> 	xchg bx, ax			; bx = displacement (-1 to -256)
   497                              <1> 
   498                              <1> .match_cx_plus_2:
   499 00000287 41                  <1> 	inc cx
   500                              <1> .match_cx_plus_1:
   501 00000288 41                  <1> 	inc cx
   502                              <1> 
   503                              <1> 		; INP:	es:di -> destination
   504                              <1> 		;	bx = match displacement (-1 to -8192)
   505                              <1> 		;	cx = match count (2 to 256)
   506                              <1> .match:
   507 00000289 294EF4              <1> 	sub word [bp + ?dst_remaining], cx
   508 0000028C 835EF600            <1> 	sbb word [bp + ?dst_remaining + 2], 0
   509                              <1> d0	mov byte [bp + ?errordata], 85h
   510 00000290 726F                <1> 	jc .error
   511                              <1> 
   512 00000292 89F8                <1> 	mov ax, di
   513 00000294 01D8                <1> 	add ax, bx			; ax -> match offset
   514                              <1> d0	mov byte [bp + ?errordata], 83h
   515 00000296 7369                <1> 	jnc .error			; ax must be below di !
   516 00000298 57                  <1> 	push di
   517                              <1> 
   518                              <1> %if _TESTFILE
   519                              <1> 	rol byte [ss:verbose], 1
   520                              <1> 	jnc @F
   521                              <1> 	push es
   522                              <1> 	push ds
   523                              <1> 	push ax
   524                              <1> 	push bx
   525                              <1> 	push cx
   526                              <1> 	push dx
   527                              <1> 	push di
   528                              <1> 
   529                              <1> 	 push ds
   530                              <1> 	 push si
   531                              <1> 	 push es
   532                              <1> 	 push di
   533                              <1> 	push ss
   534                              <1> 	pop es
   535                              <1> 	mov ax, cx
   536                              <1> 	mov di, msg.verbose.2.length
   537                              <1> 	call store_hex_word
   538                              <1> 	mov ax, bx
   539                              <1> 	neg ax
   540                              <1> 	mov di, msg.verbose.2.index
   541                              <1> 	call store_hex_word
   542                              <1> 
   543                              <1> 	mov ax, word [bp + ?tagword]
   544                              <1> 	mov di, msg.verbose.2.masque
   545                              <1> 	call store_hex_word
   546                              <1> 
   547                              <1> 	call get_tagbitsleft
   548                              <1> 	mov di, msg.verbose.2.left
   549                              <1> 	call store_hex_byte
   550                              <1> 
   551                              <1> 	 push word [bp + ?original_dst + 2]
   552                              <1> 	 push word [bp + ?original_dst]
   553                              <1> 	call pointer_to_linear
   554                              <1> 
   555                              <1> 	xchg cx, ax
   556                              <1> 	xchg bx, dx
   557                              <1> 
   558                              <1> 	 ; es:di on stack
   559                              <1> 	call pointer_to_linear
   560                              <1> 
   561                              <1> 	sub ax, cx
   562                              <1> 	sbb dx, bx
   563                              <1> 
   564                              <1> 	mov di, msg.verbose.2.destlow
   565                              <1> 	call store_hex_word
   566                              <1> 	xchg ax, dx
   567                              <1> 	mov di, msg.verbose.2.desthigh
   568                              <1> 	call store_hex_word
   569                              <1> 
   570                              <1> 	 push word [bp + ?original_src + 2]
   571                              <1> 	 push word [bp + ?original_src]
   572                              <1> 	call pointer_to_linear
   573                              <1> 
   574                              <1> 	xchg cx, ax
   575                              <1> 	xchg bx, dx
   576                              <1> 
   577                              <1> 	 ; ds:si on stack
   578                              <1> 	call pointer_to_linear
   579                              <1> 
   580                              <1> 	sub ax, cx
   581                              <1> 	sbb dx, bx
   582                              <1> 
   583                              <1> 	mov di, msg.verbose.2.srclow
   584                              <1> 	call store_hex_word
   585                              <1> 	xchg ax, dx
   586                              <1> 	mov di, msg.verbose.2.srchigh
   587                              <1> 	call store_hex_word
   588                              <1> 
   589                              <1> 	push ss
   590                              <1> 	pop ds
   591                              <1> 	mov dx, msg.verbose.2
   592                              <1> 	call disp_msg_counted
   593                              <1> 
   594                              <1> 	pop di
   595                              <1> 	pop dx
   596                              <1> 	pop cx
   597                              <1> 	pop bx
   598                              <1> 	pop ax
   599                              <1> 	pop ds
   600                              <1> 	pop es
   601                              <1> @@:
   602                              <1> %endif
   603                              <1> 
   604                              <1> @@:
   605 00000299 268A01              <1> 	mov al, byte [es:di + bx]	; load from window
   606 0000029C AA                  <1> 	stosb				; store, increment di
   607 0000029D E2FA                <1> 	loop @B				; loop until -- cx == 0
   608 0000029F 58                  <1> 	pop ax				; = prior di
   609 000002A0 39C7                <1> 	cmp di, ax
   610                              <1> d0	mov byte [bp + ?errordata], 82h
   611 000002A2 765D                <1> 	jbe .error			; di must be above ax !
   612                              <1> 
   613                              <1> %if _ALLOW_OVERLAPPING
   614 000002A4 E89A00              <1> 	call check_pointers_not_overlapping
   615                              <1> 					; CHG: ax, bx, cx, dx
   616                              <1> d0	mov byte [bp + ?errordata], 7Ch
   617 000002A7 7258                <1> 	jc .error
   618                              <1> %endif
   619                              <1> 
   620                              <1> .loop_j1:
   621 000002A9 EBB2                <1> 	jmp .loop
   622                              <1> 
   623                              <1> .combined:
   624 000002AB E87700              <1> 	call load_word			; load combined word
   625                              <1> 
   626 000002AE 89C3                <1> 	mov bx, ax
   627 000002B0 F9                  <1> 	stc				; CY
   628 000002B1 D0DF                <1> 	rcr bh, 1			; rotate in a 1
   629 000002B3 D0FF                <1> 	sar bh, 1
   630 000002B5 D0FF                <1> 	sar bh, 1			; fill top three bits with 1s
   631                              <1> %if _4
   632                              <1> 	sar bh, 1			; fill top *four* bits with 1s
   633                              <1> 	and ah, 15
   634                              <1> %else
   635 000002B7 80E407              <1> 	and ah, 7
   636                              <1> %endif
   637 000002BA 88E1                <1> 	mov cl, ah			; ch already = 0
   638 000002BC 75C9                <1> 	jnz .match_cx_plus_2		; length = cx + 2, bx = displacement
   639                              <1> 
   640                              <1> .escape:
   641 000002BE E87500              <1> 	call load_byte			; ah = 0
   642 000002C1 3C01                <1> 	cmp al, 1
   643 000002C3 722F                <1> 	jb .end_check
   644 000002C5 91                  <1> 	xchg cx, ax			; cx = length
   645 000002C6 77C0                <1> 	ja .match_cx_plus_1		; length = cx + 1, bx = displacement
   646                              <1> 
   647                              <1> %if _LONGLITERAL
   648 000002C8 87CB                <1> 	xchg cx, bx			; cx = displacement, top 4 or 3 bits sets
   649                              <1>  %if _4
   650                              <1> 	and ch, ~ 1111_0000b		; isolate 12-bit displacement
   651                              <1>  %else
   652 000002CA 80E51F              <1> 	and ch, ~ 1110_0000b		; isolate 13-bit displacement
   653                              <1>  %endif
   654 000002CD E308                <1>  	jcxz .normalise			; displacement 0 means segment change -->
   655 000002CF 83F91A              <1>  	cmp cx, 26			; long literals command needs >= 26 bytes
   656 000002D2 722D                <1>  	jb .error			; (reserved for future expansion)
   657                              <1> %if _TESTFILE
   658                              <1> 	push dx
   659                              <1> 	mov dx, msg.extra.4.longliteral
   660                              <1> 	call disp_command
   661                              <1> 	pop dx
   662                              <1> %endif
   663 000002D4 E961FF              <1>  	jmp .loop_literal		; process the literals -->
   664                              <1> %endif
   665                              <1> .normalise:
   666                              <1> %if _TESTFILE
   667                              <1> 	push dx
   668                              <1> 	mov dx, msg.extra.4.segchange
   669                              <1> 	call disp_command
   670                              <1> 	pop dx
   671                              <1> %endif
   672                              <1> 
   673 000002D7 E87B00              <1> 	call normalise_dssi_pointer
   674 000002DA 89F8                <1> 	mov ax, di
   675 000002DC B104                <1> 	mov cl, 4
   676 000002DE 2D0020              <1> 	sub ax, 8192			; large enough offset ?
   677                              <1> d0	mov byte [bp + ?errordata], 87h
   678 000002E1 721E                <1> 	jb .error			; no -->
   679 000002E3 83E70F              <1> 	and di, 15
   680 000002E6 81C70020            <1> 	add di, 8192			; 8192 .. 8207
   681 000002EA D3E8                <1> 	shr ax, cl			; how many paragraphs to advance
   682 000002EC 8CC1                <1> 	mov cx, es
   683 000002EE 01C1                <1> 	add cx, ax			; => new window
   684 000002F0 8EC1                <1> 	mov es, cx
   685 000002F2 EBB5                <1> 	jmp .loop_j1
   686                              <1> 
   687                              <1> .end_check:
   688                              <1> %if _TESTFILE
   689                              <1> 	push dx
   690                              <1> 	mov dx, msg.extra.4.eos
   691                              <1> 	call disp_command
   692                              <1> 	pop dx
   693                              <1> %endif
   694                              <1> 
   695                              <1> d0	mov byte [bp + ?errordata], 7Dh
   696 000002F4 31C9                <1> 	xor cx, cx
   697 000002F6 394EFA              <1> 	cmp word [bp + ?src_remaining + 2], cx
   698 000002F9 7506                <1> 	jne .error
   699 000002FB 394EF8              <1> 	cmp word [bp + ?src_remaining], cx
   700 000002FE 7501                <1> 	jne .error
   701                              <1> 
   702                              <1> .end:
   703 00000300 A8                  <1> 	db __TEST_IMM8			; (NC)
   704                              <1> .error:
   705 00000301 F9                  <1> 	stc
   706                              <1> 
   707                              <1> %if _COUNTER
   708 00000302 9F                  <1> 	lahf
   709 00000303 B00D                <1> 	mov al, 13
   710 00000305 E8B2FE              <1> 	call disp_al_for_progress
   711 00000308 B00A                <1> 	mov al, 10
   712 0000030A E8ADFE              <1> 	call disp_al_for_progress
   713 0000030D 9E                  <1> 	sahf
   714                              <1> %endif
   715                              <1> d0	mov bx, word [bp + ?errordata]
   716                              <1> %if _TESTFILE
   717                              <1>  %assign _TESTFILE_SUPPORTED 1
   718                              <1> %endif
   719 0000030E 89EC5D              <1> 	lleave code
   720 00000311 C3                  <1> 	lret
   721                              <1> 
   722                              <1> 
   723                              <1> 		; INP:	ds:si -> source
   724                              <1> 		;	?src_remaining
   725                              <1> 		;	word [?tagword] = tag word
   726                              <1> 		;	word [?tagbitscycle] = circular tag bits indicator
   727                              <1> 		;	 (there's always a single bit set in this word.
   728                              <1> 		;	 if this word is equal to 1 on INP then the tag
   729                              <1> 		;	 word must be reloaded, and the last bit shifted
   730                              <1> 		;	 out of the INP prior tag word.)
   731                              <1> 		; OUT:	NC if read a zero,
   732                              <1> 		;	CY if read a one,
   733                              <1> 		;	 ds:si = incremented source (not normalised)
   734                              <1> 		;	 ?src_remaining decremented
   735                              <1> 		;	 word [?tagword] updated
   736                              <1> 		;	 word [?tagbitscycle] updated
   737                              <1> 		;	branches to depack.error on error
   738                              <1> 		; CHG:	si, ax
   739                              <1> get_bit:
   740 00000312 D14EF0              <1> 	ror word [bp + ?tagbitscycle], 1
   741 00000315 730A                <1> 	jnc .left
   742                              <1> 		; after this branch not taken, the cycle word
   743                              <1> 		;  wraps around to be equal to 8000h. this
   744                              <1> 		;  will wrap around again after 15 more ror.
   745 00000317 E80B00              <1> 	call load_word
   746 0000031A D16EF2              <1> 	shr word [bp + ?tagword], 1
   747 0000031D 8946F2              <1> 	mov word [bp + ?tagword], ax
   748 00000320 C3                  <1> 	retn
   749                              <1> 
   750                              <1> .left:
   751 00000321 D16EF2              <1> 	shr word [bp + ?tagword], 1
   752 00000324 C3                  <1> 	retn
   753                              <1> 
   754                              <1> 		; lodsw with ?src_remaining check
   755                              <1> load_word:
   756 00000325 83FEFE              <1> 	cmp si, -2			; would overflow ?
   757                              <1> d0	mov byte [bp + ?errordata], 86h
   758 00000328 73D7                <1> 	jae depack.error
   759                              <1> 		; The above check needs to be done before the lodsw
   760                              <1> 		;  so that lodsw never runs with si = 0FFFFh which
   761                              <1> 		;  would fault on some machines.
   762 0000032A 836EF802            <1> 	sub word [bp + ?src_remaining], 2
   763 0000032E AD                  <1> 	lodsw
   764                              <1> 
   765                              <1> sbb_src_remaining_check:
   766 0000032F 835EFA00            <1> 	sbb word [bp + ?src_remaining + 2], 0
   767                              <1> d0	mov byte [bp + ?errordata], 84h
   768 00000333 72CC                <1> 	jc depack.error
   769 00000335 C3                  <1> 	retn
   770                              <1> 
   771                              <1> 		; lodsb with ?src_remaining check
   772                              <1> load_byte:
   773 00000336 AC                  <1> 	lodsb
   774 00000337 85F6                <1> 	test si, si			; overflowed ?
   775                              <1> d0	mov byte [bp + ?errordata], 81h
   776 00000339 74C6                <1> 	jz depack.error
   777 0000033B 836EF801            <1> 	sub word [bp + ?src_remaining], 1
   778 0000033F EBEE                <1> 	jmp sbb_src_remaining_check
   779                              <1> 
   780                              <1> 
   781                              <1> %if _TESTFILE
   782                              <1> disp_command:
   783                              <1> 	rol byte [ss:commandsextraverbose], 1
   784                              <1> 	jc .do
   785                              <1> 	rol byte [ss:extraverbose], 1
   786                              <1> 	jc .do
   787                              <1> 	cmp dx, msg.extra.4.longliteral
   788                              <1> 	je @F
   789                              <1> 	rol byte [ss:commandsverbose], 1
   790                              <1> 	jnc @F
   791                              <1> .do:
   792                              <1> 	push es
   793                              <1> 	push ds
   794                              <1> 	push ax
   795                              <1> 	push bx
   796                              <1> 	push cx
   797                              <1> 	push dx
   798                              <1> 	push di
   799                              <1> 
   800                              <1> 	 push ds
   801                              <1> 	 push si
   802                              <1> 	 push es
   803                              <1> 	 push di
   804                              <1> 	push ss
   805                              <1> 	pop ds
   806                              <1> 	call disp_msg_counted
   807                              <1> 
   808                              <1> 	push ss
   809                              <1> 	pop es
   810                              <1> 	mov ax, word [bp + ?tagword]
   811                              <1> 	mov di, msg.extra.3.masque
   812                              <1> 	call store_hex_word
   813                              <1> 
   814                              <1> 	call get_tagbitsleft
   815                              <1> 	mov di, msg.extra.3.left
   816                              <1> 	call store_hex_byte
   817                              <1> 
   818                              <1> 	 push word [bp + ?original_dst + 2]
   819                              <1> 	 push word [bp + ?original_dst]
   820                              <1> 	call pointer_to_linear
   821                              <1> 
   822                              <1> 	xchg cx, ax
   823                              <1> 	xchg bx, dx
   824                              <1> 
   825                              <1> 	 ; es:di on stack
   826                              <1> 	call pointer_to_linear
   827                              <1> 
   828                              <1> 	sub ax, cx
   829                              <1> 	sbb dx, bx
   830                              <1> 
   831                              <1> 	mov di, msg.extra.3.destlow
   832                              <1> 	call store_hex_word
   833                              <1> 	xchg ax, dx
   834                              <1> 	mov di, msg.extra.3.desthigh
   835                              <1> 	call store_hex_word
   836                              <1> 
   837                              <1> 	 push word [bp + ?original_src + 2]
   838                              <1> 	 push word [bp + ?original_src]
   839                              <1> 	call pointer_to_linear
   840                              <1> 
   841                              <1> 	xchg cx, ax
   842                              <1> 	xchg bx, dx
   843                              <1> 
   844                              <1> 	 ; ds:si on stack
   845                              <1> 	call pointer_to_linear
   846                              <1> 
   847                              <1> 	sub ax, cx
   848                              <1> 	sbb dx, bx
   849                              <1> 
   850                              <1> 	mov di, msg.extra.3.srclow
   851                              <1> 	call store_hex_word
   852                              <1> 	xchg ax, dx
   853                              <1> 	mov di, msg.extra.3.srchigh
   854                              <1> 	call store_hex_word
   855                              <1> 
   856                              <1> 	push ss
   857                              <1> 	pop ds
   858                              <1> 	mov dx, msg.extra.3
   859                              <1> 	call disp_msg_counted
   860                              <1> 
   861                              <1> 	pop di
   862                              <1> 	pop dx
   863                              <1> 	pop cx
   864                              <1> 	pop bx
   865                              <1> 	pop ax
   866                              <1> 	pop ds
   867                              <1> 	pop es
   868                              <1> @@:
   869                              <1> 	retn
   870                              <1> 
   871                              <1> 
   872                              <1> 		; Convert cycle mask to a counter
   873                              <1> get_tagbitsleft:
   874                              <1> 	push bx
   875                              <1> 	mov bx, word [bp + ?tagbitscycle]
   876                              <1> 	xor ax, ax
   877                              <1> @@:
   878                              <1> 	inc ax
   879                              <1> 	ror bx, 1
   880                              <1> 	jnc @B
   881                              <1> 	pop bx
   882                              <1> 	retn
   883                              <1> %endif
  1840                                  %endif
  1841                                  
  1842                                  
  1843                                  %if _ALLOW_OVERLAPPING
  1844                                  		; INP:	?src, ?dst
  1845                                  		; OUT:	CY if error (?src < ?dst)
  1846                                  		;	NC if success
  1847                                  		; CHG:	ax, bx, cx, dx
  1848                                  check_pointers_not_overlapping:
  1849                                  %if CHECK_POINTERS_VARIABLE_DST
  1850                                  	 push word [bp + ?dst + 2]
  1851                                  	 push word [bp + ?dst]
  1852                                  %else
  1853 00000341 06                      	 push es
  1854 00000342 57                      	 push di
  1855                                  %endif
  1856 00000343 E84700                  	call pointer_to_linear
  1857                                  
  1858 00000346 91                      	xchg cx, ax
  1859 00000347 87DA                    	xchg bx, dx			; bx:cx = linear ?dst after write
  1860                                  
  1861                                  %if CHECK_POINTERS_VARIABLE_SRC
  1862                                  	 push word [bp + ?src + 2]
  1863                                  	 push word [bp + ?src]
  1864                                  %else
  1865 00000349 1E                      	 push ds
  1866 0000034A 56                      	 push si
  1867                                  %endif
  1868 0000034B E83F00                  	call pointer_to_linear		; dx:ax = linear ?src before next read
  1869                                  
  1870 0000034E 39DA                    	cmp dx, bx			; ?src >= ?dst ?
  1871 00000350 7502                    	jne @F
  1872 00000352 39C8                    	cmp ax, cx
  1873                                  @@:
  1874                                  					; (CY) if error (src < dst)
  1875                                  					; (NC) if no error
  1876 00000354 C3                      	retn
  1877                                  %endif
  1878                                  
  1879                                  	; This leaves the lframe context created within the
  1880                                  	;  specific depacker's file. The above function
  1881                                  	;  check_pointers_not_overlapping uses the frame.
  1882                                  	lleave ctx
  1883                                  
  1884                                  
  1885                                  		; INP:	ds:si = pointer
  1886                                  		;	es:di = pointer
  1887                                  		; OUT:	ds:si normalised
  1888                                  		;	es:di normalised
  1889                                  %if NEED_NORMALISE_BOTH_POINTERS
  1890                                  normalise_both_pointers:
  1891                                  	 push es
  1892                                  	 push di
  1893                                  	call normalise_pointer
  1894                                  	 pop di
  1895                                  	 pop es
  1896                                  %endif
  1897                                  
  1898                                  normalise_dssi_pointer:
  1899 00000355 1E                      	 push ds
  1900 00000356 56                      	 push si
  1901 00000357 E80300                  	call normalise_pointer
  1902 0000035A 5E                      	 pop si
  1903 0000035B 1F                      	 pop ds
  1904 0000035C C3                      	retn
  1905                                  
  1906                                  
  1907                                  		; INP:	word [ss:sp + 2] = segment
  1908                                  		;	word [ss:sp] = offset
  1909                                  		;
  1910                                  		; Note:	Does not work correctly with pointers that point to
  1911                                  		;	 a HMA location. Do not use then!
  1912                                  normalise_pointer:
  1913                                  %if NEED_NORMALISE_POINTER_WITH_DISPLACEMENT
  1914                                  	lframe near
  1915                                  	lpar word,	segment
  1916                                  	lpar word,	offset
  1917                                  	lpar_return
  1918                                  	lenter
  1919                                  
  1920                                  	cmp word [bp + ?offset], 15
  1921                                  	jbe .ret
  1922                                  
  1923                                  	push bx
  1924                                  	push cx
  1925                                  
  1926                                  	xor bx, bx
  1927                                  	xor cx, cx
  1928                                  	 push word [bp + ?segment]
  1929                                  	 push word [bp + ?offset]
  1930                                  	call normalise_pointer_with_displacement_bxcx
  1931                                  	 pop word [bp + ?offset]
  1932                                  	 pop word [bp + ?segment]
  1933                                  
  1934                                  	pop cx
  1935                                  	pop bx
  1936                                  .ret:
  1937                                  	lleave
  1938                                  	lret
  1939                                  
  1940                                  
  1941                                  		; INP:	word [ss:sp + 2] = segment
  1942                                  		;	word [ss:sp] = offset
  1943                                  		;	bx:cx = add/sub displacement
  1944                                  		; OUT:	CY if the displacement carries
  1945                                  		;	NC if not
  1946                                  normalise_pointer_with_displacement_bxcx:
  1947                                  %endif
  1948                                  	lframe near
  1949                                  	lpar word,	segment
  1950                                  	lpar word,	offset
  1951                                  	lpar_return
  1952 0000035D 5589E5                  	lenter
  1953                                  
  1954                                  %ifn NEED_NORMALISE_POINTER_WITH_DISPLACEMENT
  1955 00000360 837E040F                	cmp word [bp + ?offset], 15
  1956 00000364 7625                    	jbe .ret
  1957                                  %endif
  1958                                  
  1959 00000366 50                      	push ax
  1960 00000367 51                      	push cx
  1961 00000368 52                      	push dx
  1962                                  
  1963 00000369 FF7606                  	 push word [bp + ?segment]
  1964 0000036C FF7604                  	 push word [bp + ?offset]
  1965 0000036F E81B00                  	call pointer_to_linear
  1966                                  
  1967                                  %if NEED_NORMALISE_POINTER_WITH_DISPLACEMENT
  1968                                  	; push bx
  1969                                  	; 				; sign-extend cx into bx:cx
  1970                                  	; cmp cx, 8000h			; CY if < 8000h (NC if negative)
  1971                                  	; cmc				; NC if positive
  1972                                  	; sbb bx, bx			; 0 if was NC, -1 if was CY
  1973                                  
  1974                                  	add cx, ax
  1975                                  	adc dx, bx			; dx:cx = dx:ax + bx:cx
  1976                                  	; pop bx
  1977                                  	lahf				; ah = flags
  1978                                  %else
  1979 00000372 91                      	xchg ax, cx
  1980                                  %endif
  1981                                  
  1982                                  %if 0
  1983                                  		; Adds in HMA support for this function. Not currently used.
  1984                                  	cmp dx, 10h			; dx:ax >= 10_0000h ?
  1985                                  	jb @F				; no, linear-to-pointer normally -->
  1986                                  	; ja .error
  1987                                  
  1988                                  	add cx, 10h
  1989                                  	; jc .error
  1990                                  	mov word [bp + ?offset], cx
  1991                                  	or word [bp + ?segment], -1
  1992                                  	jmp .return
  1993                                  @@:
  1994                                  %endif
  1995                                  
  1996 00000373 53                      	push bx
  1997 00000374 89CB                    	mov bx, cx
  1998 00000376 83E10F                  	and cx, 15
  1999 00000379 894E04                  	mov word [bp + ?offset], cx
  2000                                  
  2001 0000037C B104                    	mov cl, 4
  2002                                  @@:
  2003 0000037E D1EA                    	shr dx, 1
  2004 00000380 D1DB                    	rcr bx, 1
  2005 00000382 E2FA                    	loop @B
  2006                                  
  2007 00000384 895E06                  	mov word [bp + ?segment], bx
  2008 00000387 5B                      	pop bx
  2009                                  
  2010                                  	; test dx, dx
  2011                                  	; jnz .error
  2012                                  
  2013                                  .return:
  2014                                  
  2015                                  %if NEED_NORMALISE_POINTER_WITH_DISPLACEMENT
  2016                                  	sahf				; restore flags from ah
  2017                                  %endif
  2018 00000388 5A                      	pop dx
  2019 00000389 59                      	pop cx
  2020 0000038A 58                      	pop ax
  2021                                  %ifn NEED_NORMALISE_POINTER_WITH_DISPLACEMENT
  2022                                  .ret:
  2023                                  %endif
  2024 0000038B 5D                      	lleave
  2025 0000038C C3                      	lret
  2026                                  
  2027                                  
  2028                                  		; INP:	word [ss:sp + 2] = segment
  2029                                  		;	word [ss:sp] = offset
  2030                                  		; OUT:	dx:ax = linear address
  2031                                  pointer_to_linear:
  2032                                  	lframe near
  2033                                  	lpar word,	segment
  2034                                  	lpar word,	offset
  2035 0000038D 5589E5                  	lenter
  2036                                  
  2037 00000390 8B4606                  	mov ax, word [bp + ?segment]
  2038 00000393 31D2                    	xor dx, dx
  2039 00000395 51                      	push cx
  2040 00000396 B90400                  	mov cx, 4
  2041                                  @@:
  2042 00000399 D1E0                    	shl ax, 1
  2043 0000039B D1D2                    	rcl dx, 1
  2044 0000039D E2FA                    	loop @B
  2045                                  
  2046 0000039F 034604                  	add ax, word [bp + ?offset]
  2047 000003A2 11CA                    	adc dx, cx			; cx = 0 here
  2048 000003A4 59                      	pop cx
  2049                                  
  2050 000003A5 5D                      	lleave
  2051 000003A6 C20400                  	lret
  2052                                  
  2053                                  
  2054                                  %if _PASSLCFG
  2055 000003A9 90<rep 7h>              	align 16
  2056                                  transfer_lcfg_block:
  2057 000003B0 90<rep 20h>             	times lcfg.size nop
  2058                                  %endif
  2059                                  	align 16
  2060                                  init1_end:
  2061                                  
  2062                                  
  2063                                  	usesection INIT0
  2064                                  %if _TEST_PROGRAM
  2065                                  init0_msg:
  2066                                  %if (_INCLUDE_UNCOMPRESSED && ! _INCLUDE_UNCOMPRESSED_IN_IMAGE) || _RELOAD_FILE
  2067                                  .error_stderr_file:	db "Error: Unable to open own executable file.",13,10
  2068                                  .error_stderr_file.length equ $ - .error_stderr_file
  2069                                  %endif
  2070 000001B2 4572726F723A204E6F-     .error_stderr:	db "Error: Not enough memory allocated.",13,10
  2070 000001BB 7420656E6F75676820-
  2070 000001C4 6D656D6F727920616C-
  2070 000001CD 6C6F63617465642E0D-
  2070 000001D6 0A                 
  2071                                  .error_stderr.length: equ $ - .error_stderr
  2072                                  .error_c_stdout:
  2073 000001D7 30                      .error_stdout:	db "0"
  2074                                  %if 0
  2075                                  		_autodigits paras(_TEST_PROGRAM_DECOMPRESSED_SIZE 				+ (payload_end - payload) 				+ (init1_end - init1_start) 				+ ADDITIONAL_MEMORY 				)
  2080                                  %endif
  2081 000001D8 0D0A                    		db 13,10
  2082                                  .error_c_stdout.length: equ $ - .error_c_stdout
  2083                                  .error_stdout.length: equ $ - .error_stdout
  2084                                  
  2085 000001DA 90<rep 226h>            	align 1024
  2086                                  %if ($ - $$) != 1024
  2087                                   %error Wrong INIT0 size
  2088                                  %endif
  2089                                  %endif
  2090                                  
  2091                                  	align 16
  2092                                  init0_end:
  2093                                  
  2094                                  
  2095                                  %assign num (init1_end - init1_start) + (init0_end - init0_start)
  2096                                  %if _BRIEFLZ
  2097                                  %define which iniblz
  2098                                  %elif _LZ4
  2099                                  %define which inilz4
  2100                                  %elif _SNAPPY
  2101                                  %define which inisz
  2102                                  %elif _EXODECR
  2103                                  %define which iniexo
  2104                                  %elif _X
  2105                                  %define which inix
  2106                                  %elif _HEATSHRINK
  2107                                  %define which inihs
  2108                                  %elif _LZD
  2109                                  %define which inilz
  2110                                  %elif _LZO
  2111                                  %define which inilzo
  2112                                  %elif _LZSA2
  2113                                  %define which inilzsa2
  2114                                  %elif _APL
  2115                                  %define which iniapl
  2116                                  %elif _BZP
  2117                                  %define which inibzp
  2118                                  %elif _ZEROCOMP
  2119                                  %define which inizero
  2120                                  %elif _MVCOMP
  2121                                  %define which inimv
  2122                                  %elif _LZEXEDAT
  2123                                  %define which inilzexe
  2124                                  %endif
  2125                                  %warning which: num bytes used for depacker
  2125          ******************       warning: inilzexe: 2000 bytes used for depacker [-w+user]
  2126                                  
  2127                                  
  2128                                  %if _TEST_PROGRAM
  2129                                  	addsection INIT2, align=16 follows=INIT1 vstart=0
  2130                                  init2_start:
  2131                                  		; si => after PSP
  2132                                  		; cs => INIT2
  2133                                  		; psp, free, payload, init1, init2, payload space, stack
  2134                                  		;
  2135                                  		; The correct allocation for the test program
  2136                                  		;  is image size (init0, payload, init1, init2)
  2137                                  		;  minus init0 plus compressed payload size
  2138                                  		;  plus decompressed size plus stack. For
  2139                                  		;  simplicity, init0 subtraction may be skipped.
  2140                                  
  2141                                  		; ss:sp -> word amount repetitions, word ax
  2142                                  		; bx = 1 if A mode test,
  2143                                  		;	8001h if B mode test,
  2144                                  		;	4001h if C mode test
  2145 00000000 53                      	push bx			; push into ?whichtest
  2146                                  
  2147                                  	lframe 0
  2148                                  %if (_INCLUDE_UNCOMPRESSED && ! _INCLUDE_UNCOMPRESSED_IN_IMAGE) || _RELOAD_FILE
  2149                                  	lpar word,	handle
  2150                                  %endif
  2151                                  	lpar word,	repetitions
  2152                                  	lpar word,	whichtest
  2153                                  %if _RELOAD_XMS
  2154                                   	lvar dword, xmsentry
  2155                                   	lvar word, xmshandle
  2156                                  %endif
  2157                                  %if _INCLUDE_UNCOMPRESSED && ! _INCLUDE_UNCOMPRESSED_IN_IMAGE
  2158                                  	lequ 128,	buffersize
  2159                                  	lvar ?buffersize,	buffer
  2160                                  %endif
  2161 00000001 5589E5                  	lenter
  2162                                  
  2163                                  %if _RELOAD_FILE && _RELOAD_XMS
  2164                                  	or word [bp + ?xmshandle], -1
  2165                                  %endif
  2166                                  
  2167 00000004 8B5604                  	mov dx, word [bp + ?repetitions]
  2168 00000007 83FAFF                  	cmp dx, -1
  2169 0000000A 7509                    	jne @F
  2170                                  
  2171                                  .cmdline_error:
  2172                                  %if _DEBUG0
  2173                                  	mov bx, -1
  2174                                  %endif
  2175 0000000C BA[D602]                	mov dx, init2_msg.cmdline_error
  2176 0000000F B92400                  	mov cx, init2_msg.cmdline_error.length
  2177 00000012 E98401                  	jmp init2_error
  2178                                  
  2179                                  
  2180                                  @@:
  2181 00000015 F6460340                	testopt [bp + ?whichtest], 4000h
  2182 00000019 750C                    	jnz .a_or_c
  2183 0000001B F6460380                	testopt [bp + ?whichtest], 8000h
  2184 0000001F 7406                    	jz .a_or_c
  2185                                  .b:
  2186 00000021 85D2                    	test dx, dx
  2187 00000023 74E7                    	jz .cmdline_error
  2188 00000025 EB04                    	jmp @F
  2189                                  
  2190                                  .a_or_c:
  2191 00000027 85D2                    	test dx, dx
  2192 00000029 75E1                    	jnz .cmdline_error
  2193                                  @@:
  2194                                  
  2195                                  %if _RELOAD_XMS
  2196                                  	push si
  2197                                  	mov ax, 4300h
  2198                                  	int 2Fh
  2199                                  	cmp al, 80h
  2200                                  %if _RELOAD_FILE
  2201                                  	jne .noxms
  2202                                  %else
  2203                                  	jne init2_error_xms
  2204                                  %endif
  2205                                  	mov ax, 4310h
  2206                                  	int 2Fh
  2207                                  	mov word [bp + ?xmsentry], bx
  2208                                  	mov word [bp + ?xmsentry + 2], es
  2209                                  	mov ah, 09h
  2210                                  	mov dx, KiB(payload_end - payload)
  2211                                  	call far [bp + ?xmsentry]
  2212                                  	cmp ax, 1
  2213                                  %if _RELOAD_FILE
  2214                                  	jne .noxms
  2215                                  %else
  2216                                  	jne init2_error_xms
  2217                                  %endif
  2218                                  	mov word [bp + ?xmshandle], dx
  2219                                  	mov ax, cs
  2220                                  	sub ax, ( (init1_end - init1_start) 		+ (payload_end - payload) 		) >> 4		; => payload source for first run
  2223                                  	 push cs
  2224                                  	 pop ds
  2225                                  	mov si, init2_xmsm_to_save
  2226                                  	mov word [si + XMSM.dsthdl], dx
  2227                                  	mov word [si + XMSM.srcadr + 2], ax
  2228                                  %ifn _RELOAD_FILE
  2229                                  	push ax
  2230                                  %endif
  2231                                  	mov ah, 0Bh
  2232                                  	call far [bp + ?xmsentry]
  2233                                  	cmp ax, 1
  2234                                  	jne init2_error_xms_free
  2235                                  %ifn _RELOAD_FILE
  2236                                  	pop ax			; => payload
  2237                                  %else
  2238                                  .noxms:
  2239                                  	mov ax, cs
  2240                                  	sub ax, ( (init1_end - init1_start) 		+ (payload_end - payload) 		) >> 4		; => payload source for first run
  2243                                  @@:
  2244                                  %endif
  2245                                  	pop si
  2246                                  %elif _RELOAD_FILE
  2247                                  	mov ax, cs
  2248                                  	sub ax, ( (init1_end - init1_start) 		+ (payload_end - payload) 		) >> 4		; => payload source for first run
  2251                                  %else
  2252 0000002B 8CCA                    	mov dx, cs
  2253 0000002D 81C26214                	add dx, (init2_end - init2_start) >> 4
  2254                                  				; => payload saving area
  2255 00000031 8CC8                    	mov ax, cs
  2256 00000033 2D260F                  	sub ax, ( (init1_end - init1_start) 		+ (payload_end - payload) 		) >> 4		; => payload source for first run
  2259 00000036 B9E90E                  	mov cx, (payload_end - payload) >> 4
  2260 00000039 E8C102                  	call init2_movp		; copy payload to payload saving area
  2261                                  %endif
  2262                                  		; We save away the payload here because a failure
  2263                                  		;  to decompress generally overwrites part of that
  2264                                  		;  payload which was used as source.
  2265                                  
  2266 0000003C 89C2                    	mov dx, ax		; dx => payload source to use
  2267 0000003E 8CC8                    	mov ax, cs
  2268 00000040 83E83D                  	sub ax, (init1_end - init1_start) >> 4
  2269                                  				; ax => INIT1
  2270 00000043 BB0100                  	mov bx, 1		; say we're in EXE mode
  2271 00000046 52                      	push dx
  2272 00000047 50                      	push ax
  2273 00000048 56                      	push si			; si => target
  2274 00000049 0E                      	 push cs
  2275 0000004A E80D01                  	 call .transfer		; call decompression
  2276 0000004D 5E                      	pop si
  2277 0000004E 58                      	pop ax
  2278 0000004F 5A                      	pop dx
  2279                                  		; Returns here after decompression.
  2280                                  		; CY if error.
  2281 00000050 7309                    	jnc @F
  2282                                  
  2283 00000052 BA[2702]                	mov dx, init2_msg.initial_error
  2284 00000055 B93C00                  	mov cx, init2_msg.initial_error.length
  2285 00000058 E93E01                  	jmp init2_error_free
  2286                                  
  2287                                  @@:
  2288                                  %if _INCLUDE_UNCOMPRESSED
  2289                                   %if _INCLUDE_UNCOMPRESSED_IN_IMAGE
  2290                                  payload_uncompressed_size equ payload_uncompressed.end - payload_uncompressed
  2291                                   %else
  2292                                  payload_uncompressed_size equ _TEST_PROGRAM_DECOMPRESSED_SIZE
  2293                                   %endif
  2294 0000005B E80201                  	call checkdecompressed
  2295 0000005E 7409                    	je @F
  2296                                  
  2297                                  %if _WRITE_WRONG_FILE
  2298                                  	call writefiles
  2299                                  %endif
  2300                                  
  2301                                  %if _DEBUG0
  2302                                  	mov bx, -1
  2303                                  %endif
  2304 00000060 BA[6302]                	mov dx, init2_msg.initial_error_2
  2305 00000063 B93C00                  	mov cx, init2_msg.initial_error_2.length
  2306 00000066 E93001                  	jmp init2_error_free
  2307                                  
  2308                                  @@:
  2309                                  %endif
  2310                                  
  2311 00000069 F6460340                	testopt [bp + ?whichtest], 4000h
  2312 0000006D 741D                    	jz @F
  2313 0000006F 8CC8                    	mov ax, cs
  2314 00000071 83E83D                  	sub ax, (init1_end - init1_start) >> 4
  2315                                  				; ax => INIT1
  2316 00000074 8EC0                    	mov es, ax
  2317 00000076 26A1[4C00]              	mov ax, word [es:init1_c_mode_counter]
  2318 0000007A E85601                  	call init2_disp_ax_dec
  2319 0000007D B00D                    	mov al, 13
  2320 0000007F E84601                  	call init2_disp_al
  2321 00000082 B00A                    	mov al, 10
  2322 00000084 E84101                  	call init2_disp_al
  2323                                  %if _RELOAD_XMS
  2324                                  	call freexms
  2325                                  %endif
  2326 00000087 B8004C                  	mov ax, 4C00h
  2327 0000008A CD21                    	int 21h
  2328                                  
  2329                                  @@:
  2330                                  	lvar word,	upperbound
  2331 0000008C 52                      	 push dx
  2332                                  	lvar word,	lowerbound
  2333 0000008D 56                      	 push si
  2334                                  	lvar word,	current_init1
  2335 0000008E 50                      	 push ax
  2336                                  
  2337                                  %if _TEST_PROGRESS
  2338 0000008F BA[1C02]                	mov dx, init2_msg.progress.1
  2339 00000092 B90700                  	mov cx, init2_msg.progress.1.length
  2340                                  .loop:
  2341 00000095 0E                      	push cs
  2342 00000096 1F                      	pop ds
  2343 00000097 BB0200                  	mov bx, 2
  2344 0000009A B440                    	mov ah, 40h
  2345 0000009C CD21                    	int 21h
  2346                                  %else
  2347                                  .loop:
  2348                                  %endif
  2349                                  
  2350 0000009E 8B56FE                  	mov dx, [bp + ?upperbound]
  2351                                  
  2352 000000A1 F6460380                	testopt [bp + ?whichtest], 8000h
  2353 000000A5 7419                    	jz @F
  2354                                  
  2355 000000A7 FF4E04                  	dec word [bp + ?repetitions]
  2356 000000AA 751E                    	jnz .test_b_skip_bound
  2357                                  
  2358                                  %if _TEST_PROGRESS
  2359 000000AC 0E                      	push cs
  2360 000000AD 1F                      	pop ds
  2361 000000AE BA[2502]                	mov dx, init2_msg.progress.linebreak
  2362 000000B1 B90200                  	mov cx, init2_msg.progress.linebreak.length
  2363 000000B4 BB0200                  	mov bx, 2
  2364 000000B7 B440                    	mov ah, 40h
  2365 000000B9 CD21                    	int 21h
  2366                                  %endif
  2367                                  %if _RELOAD_XMS
  2368                                  	call freexms
  2369                                  %endif
  2370 000000BB B8004C                  	mov ax, 4C00h
  2371 000000BE CD21                    	int 21h
  2372                                  
  2373                                  
  2374                                  @@:
  2375 000000C0 2B56FC                  	sub dx, [bp + ?lowerbound]
  2376 000000C3 746C                    	jz .found
  2377 000000C5 D1EA                    	shr dx, 1
  2378                                  		; Rounding down, so that we never retry upper bound.
  2379                                  		;  The upper bound is known to be working.
  2380 000000C7 0356FC                  	add dx, [bp + ?lowerbound]
  2381                                  
  2382                                  .test_b_skip_bound:
  2383 000000CA 52                      	push dx
  2384 000000CB 81C2E90E                	add dx, (payload_end - payload) >> 4
  2385 000000CF 8B46FA                  	mov ax, [bp + ?current_init1]
  2386 000000D2 B93D00                  	mov cx, (init1_end - init1_start) >> 4
  2387 000000D5 E82502                  	call init2_movp
  2388 000000D8 8956FA                  	mov [bp + ?current_init1], dx
  2389 000000DB 5A                      	pop dx
  2390                                  
  2391                                  %if _RELOAD_XMS
  2392                                  	mov ax, [bp + ?xmshandle]
  2393                                   %if _RELOAD_FILE
  2394                                  	cmp ax, -1
  2395                                  	je .restore_no_xms
  2396                                   %endif
  2397                                  	push si
  2398                                  	 push cs
  2399                                  	 pop ds
  2400                                  	mov si, init2_xmsm_from_save
  2401                                  	mov word [si + XMSM.srchdl], ax
  2402                                  	mov word [si + XMSM.dstadr + 2], dx
  2403                                  	mov ah, 0Bh
  2404                                  	call far [bp + ?xmsentry]
  2405                                  	cmp ax, 1
  2406                                  	jne init2_error_xms_free
  2407                                  	pop si
  2408                                   %if _RELOAD_FILE
  2409                                  	jmp .restore_done
  2410                                   %endif
  2411                                  %endif
  2412                                  %if _RELOAD_FILE
  2413                                  .restore_no_xms:
  2414                                  size_compressed equ (payload.end - payload)
  2415                                  	push dx
  2416                                  	mov ds, dx
  2417                                  	mov cx, ((- size_compressed) >> 16) & 0FFFFh
  2418                                  	mov dx, (- size_compressed) & 0FFFFh
  2419                                  	mov ax, 4202h
  2420                                  	mov bx, [bp + ?handle]
  2421                                  	int 21h
  2422                                  	jc init2_error_file
  2423                                  	mov dx, size_compressed >> 16
  2424                                  	mov ax, size_compressed & 0FFFFh
  2425                                  @@:
  2426                                  	mov cx, 0FF00h
  2427                                  	test dx, dx
  2428                                  	jnz @F
  2429                                  	cmp ax, cx
  2430                                  	jae @F
  2431                                  	mov cx, ax
  2432                                  @@:
  2433                                  	sub ax, cx
  2434                                  	sbb dx, 0
  2435                                  	push dx
  2436                                  	push ax
  2437                                  	xor dx, dx
  2438                                  	mov ah, 3Fh
  2439                                  	int 21h
  2440                                  	jc init2_error_file
  2441                                  	cmp ax, cx
  2442                                  	jne init2_error_file
  2443                                  	mov dx, ds
  2444                                  	add dx, 0FF0h
  2445                                  	mov ds, dx
  2446                                  	pop ax
  2447                                  	pop dx
  2448                                  	mov cx, ax
  2449                                  	or cx, dx
  2450                                  	jnz @BB
  2451                                  	pop dx
  2452                                  .restore_done:
  2453                                  %endif
  2454                                  %ifn _RELOAD_XMS || _RELOAD_FILE
  2455 000000DC 8CC8                    	mov ax, cs
  2456 000000DE 056214                  	add ax, (init2_end - init2_start) >> 4
  2457                                  				; => payload in saving area
  2458 000000E1 B9E90E                  	mov cx, (payload_end - payload) >> 4
  2459 000000E4 E81602                  	call init2_movp		; copy payload from payload saving area
  2460                                  %endif
  2461                                  		; dx => source
  2462 000000E7 8B46FA                  	mov ax, [bp + ?current_init1]
  2463 000000EA BB0100                  	mov bx, 1
  2464 000000ED 52                      	push dx
  2465 000000EE 56                      	push si
  2466 000000EF 0E                      	 push cs
  2467 000000F0 E86700                  	 call .transfer
  2468 000000F3 5E                      	pop si
  2469 000000F4 5A                      	pop dx
  2470                                  		; Returns here after decompression.
  2471                                  		; CY if error.
  2472 000000F5 7312                    	jnc @F
  2473                                  
  2474 000000F7 F6460380                	testopt [bp + ?whichtest], 8000h
  2475 000000FB 7511                    	jnz .test_b_fail
  2476                                  
  2477                                  		; error: this attempt is one below the new lower bound
  2478 000000FD 42                      	inc dx
  2479 000000FE 8956FC                  	mov word [bp + ?lowerbound], dx
  2480                                  
  2481                                  %if _TEST_PROGRESS
  2482 00000101 BA[2302]                	mov dx, init2_msg.progress.fail
  2483 00000104 B90100                  	mov cx, init2_msg.progress.fail.length
  2484                                  %endif
  2485 00000107 EB8C                    	jmp .loop
  2486                                  
  2487                                  @@:
  2488                                  %if _INCLUDE_UNCOMPRESSED
  2489 00000109 E85400                  	call checkdecompressed
  2490 0000010C 7417                    	je @F
  2491                                  
  2492                                  %if _WRITE_WRONG_FILE
  2493                                  	call writefiles
  2494                                  %endif
  2495                                  
  2496                                  .test_b_fail:
  2497                                  %if _TEST_PROGRESS
  2498 0000010E 0E                      	push cs
  2499 0000010F 1F                      	pop ds
  2500 00000110 BA[2502]                	mov dx, init2_msg.progress.linebreak
  2501 00000113 B90200                  	mov cx, init2_msg.progress.linebreak.length
  2502 00000116 BB0200                  	mov bx, 2
  2503 00000119 B440                    	mov ah, 40h
  2504 0000011B CD21                    	int 21h
  2505                                  %endif
  2506                                  %if _DEBUG0
  2507                                  	mov bx, -2
  2508                                  %endif
  2509 0000011D BA[9F02]                	mov dx, init2_msg.subsequent_error_2
  2510 00000120 B93700                  	mov cx, init2_msg.subsequent_error_2.length
  2511 00000123 EB74                    	jmp init2_error_free
  2512                                  
  2513                                  @@:
  2514                                  %endif
  2515                                  		; success: this attempt is the new upper bound
  2516 00000125 8956FE                  	mov word [bp + ?upperbound], dx
  2517                                  %if _TEST_PROGRESS
  2518 00000128 BA[2402]                	mov dx, init2_msg.progress.success
  2519 0000012B B90100                  	mov cx, init2_msg.progress.success.length
  2520                                  %endif
  2521 0000012E E964FF                  	jmp .loop
  2522                                  
  2523                                  .found:
  2524                                  %if _TEST_PROGRESS
  2525 00000131 0E                      	push cs
  2526 00000132 1F                      	pop ds
  2527 00000133 BA[2502]                	mov dx, init2_msg.progress.linebreak
  2528 00000136 B90200                  	mov cx, init2_msg.progress.linebreak.length
  2529 00000139 BB0200                  	mov bx, 2
  2530 0000013C B440                    	mov ah, 40h
  2531 0000013E CD21                    	int 21h
  2532                                  %endif
  2533 00000140 8B46FE                  	mov ax, word [bp + ?upperbound]
  2534 00000143 29F0                    	sub ax, si		; = how many paragraphs in buffer before source
  2535 00000145 05260F                  	add ax, paras( (init1_end - init1_start) 			+ (payload_end - payload) )
  2537                                  				; = how many paragraphs needed for process
  2538 00000148 E88800                  	call init2_disp_ax_dec
  2539 0000014B B00D                    	mov al, 13
  2540 0000014D E87800                  	call init2_disp_al
  2541 00000150 B00A                    	mov al, 10
  2542 00000152 E87300                  	call init2_disp_al
  2543                                  %if _RELOAD_XMS
  2544                                  	call freexms
  2545                                  %endif
  2546 00000155 B8004C                  	mov ax, 4C00h
  2547 00000158 CD21                    	int 21h
  2548                                  
  2549                                  
  2550                                  .transfer:
  2551 0000015A 31FF                    	xor di, di
  2552 0000015C 57                      	push di			; placeholder ax value on stack
  2553 0000015D 50                      	push ax			; INIT1 segment
  2554 0000015E 57                      	push di			; zero = init1_start
  2555 0000015F CB                      	retf			; transfer to INIT1:init1_start
  2556                                  
  2557                                  
  2558                                  
  2559                                  %if _INCLUDE_UNCOMPRESSED
  2560                                  
  2561                                  
  2562                                  %if _WRITE_WRONG_FILE
  2563                                  		; INP:	si => decompressed image
  2564                                  		;	payload_uncompressed_size = size
  2565                                  		;	! _INCLUDE_UNCOMPRESSED_IN_IMAGE:
  2566                                  		;	 word [bp + ?handle] = file handle
  2567                                  		;	 [bp + ?buffer] = ?buffersize buffer
  2568                                  		; OUT:	WRONG.BIN contains what we decompressed
  2569                                  		;	WRONG2.BIN contains expected payload
  2570                                  		; CHG:	ds, si, ax, bx, cx, dx
  2571                                  		; STT:	UP
  2572                                  writefiles:
  2573                                  	push cs
  2574                                  	pop ds
  2575                                  	mov dx, init2_msg.wrong_file_name
  2576                                  	xor cx, cx
  2577                                  	mov ah, 3Ch
  2578                                  	int 21h
  2579                                  	jc .notfile
  2580                                  
  2581                                  	mov bx, ax
  2582                                  	mov cx, payload_uncompressed_size >> 4
  2583                                  	xor dx, dx
  2584                                  .loopfile:
  2585                                  	mov ds, si
  2586                                  	mov ah, 40h
  2587                                  	push cx
  2588                                  	mov cx, 16
  2589                                  	int 21h
  2590                                  	pop cx
  2591                                  	inc si
  2592                                  	loop .loopfile
  2593                                  
  2594                                  	mov ds, si
  2595                                  	mov cx, payload_uncompressed_size & 15
  2596                                  	mov ah, 40h
  2597                                  	int 21h
  2598                                  
  2599                                  	mov ah, 3Eh
  2600                                  	int 21h
  2601                                  
  2602                                  .notfile:
  2603                                  
  2604                                  	push cs
  2605                                  	pop ds
  2606                                  	mov dx, init2_msg.wrong_file_name2
  2607                                  	xor cx, cx
  2608                                  	mov ah, 3Ch
  2609                                  	int 21h
  2610                                  	jc .notfile2
  2611                                  
  2612                                  %if _INCLUDE_UNCOMPRESSED_IN_IMAGE
  2613                                  	mov bx, ax
  2614                                  	mov cx, payload_uncompressed_size >> 4
  2615                                  	mov si, cs
  2616                                  	add si, (payload_uncompressed - init2_start) >> 4
  2617                                  	xor dx, dx
  2618                                  .loopfile2:
  2619                                  	mov ds, si
  2620                                  	mov ah, 40h
  2621                                  	push cx
  2622                                  	mov cx, 16
  2623                                  	int 21h
  2624                                  	pop cx
  2625                                  	inc si
  2626                                  	loop .loopfile2
  2627                                  
  2628                                  	mov ds, si
  2629                                  	mov cx, payload_uncompressed_size & 15
  2630                                  	mov ah, 40h
  2631                                  	int 21h
  2632                                  
  2633                                  	mov ah, 3Eh
  2634                                  	int 21h
  2635                                  %else
  2636                                  	xchg si, ax
  2637                                  
  2638                                  %if _RELOAD_FILE
  2639                                  	mov cx, ((- size_compressed_plus_uncompressed) >> 16) & 0FFFFh
  2640                                  	mov dx, (- size_compressed_plus_uncompressed) & 0FFFFh
  2641                                  %else
  2642                                  	mov cx, ((- payload_uncompressed_size) >> 16) & 0FFFFh
  2643                                  	mov dx, (- payload_uncompressed_size) & 0FFFFh
  2644                                  %endif
  2645                                  	mov ax, 4202h
  2646                                  	mov bx, [bp + ?handle]
  2647                                  	int 21h
  2648                                  	jc .closefile2
  2649                                  
  2650                                  	push ss
  2651                                  	pop ds
  2652                                  	lea dx, [bp + ?buffer]
  2653                                  
  2654                                  %if payload_uncompressed_size == 0
  2655                                   %error Empty payload not allowed
  2656                                  %endif
  2657                                  %if (payload_uncompressed_size / ?buffersize) != 0
  2658                                  	mov cx, payload_uncompressed_size / ?buffersize
  2659                                  %if ?buffersize == 0 || (?buffersize & 15) != 0
  2660                                   %error Unexpected layout
  2661                                  %endif
  2662                                  .loop:
  2663                                  	push cx
  2664                                  	mov cx, ?buffersize
  2665                                  	call transferchunk
  2666                                  	pop cx
  2667                                  	jc .closefile2
  2668                                  	loop .loop
  2669                                  %endif
  2670                                  %if (payload_uncompressed_size % ?buffersize) != 0
  2671                                  	mov cx, payload_uncompressed_size % ?buffersize
  2672                                  	call transferchunk
  2673                                  %endif
  2674                                  
  2675                                  .closefile2:
  2676                                  	mov bx, si
  2677                                  	mov ah, 3Eh
  2678                                  	int 21h
  2679                                  %endif
  2680                                  
  2681                                  .notfile2:
  2682                                  	retn
  2683                                  
  2684                                  %if ! _INCLUDE_UNCOMPRESSED_IN_IMAGE
  2685                                  		; INP:	ds:dx -> buffer
  2686                                  		;	cx = size to transfer, must fit in buffer
  2687                                  		;	?handle = source file handle
  2688                                  		;	si = destination file handle
  2689                                  		; OUT:	NC if success
  2690                                  		;	CY if error
  2691                                  		; CHG:	ax, bx
  2692                                  		; STT:	UP
  2693                                  transferchunk:
  2694                                  	mov bx, word [bp + ?handle]
  2695                                  	mov ah, 3Fh
  2696                                  	int 21h
  2697                                  	jc .ret
  2698                                  	cmp ax, cx
  2699                                  	stc
  2700                                  	jne .ret		; if partial read --> (CY)
  2701                                  	mov bx, si
  2702                                  	mov ah, 40h
  2703                                  	int 21h
  2704                                  	jc .ret
  2705                                  	cmp ax, cx
  2706                                  	je .ret			; if not partial write --> (NC)
  2707                                  	stc
  2708                                  .ret:
  2709                                  	retn
  2710                                  %endif
  2711                                  
  2712                                  %endif
  2713                                  
  2714                                  
  2715                                  		; INP:	si => decompressed image
  2716                                  		;	payload_uncompressed_size = size
  2717                                  		;	! _INCLUDE_UNCOMPRESSED_IN_IMAGE:
  2718                                  		;	 word [bp + ?handle] = file handle
  2719                                  		;	 [bp + ?buffer] = ?buffersize buffer
  2720                                  		; OUT:	ZR if matching
  2721                                  		;	NZ if mismatching
  2722                                  		; CHG:	es, ds, di, bx, cx
  2723                                  		; STT:	UP
  2724                                  checkdecompressed:
  2725 00000160 50                      	push ax
  2726 00000161 52                      	push dx
  2727 00000162 56                      	push si
  2728                                  %if _INCLUDE_UNCOMPRESSED_IN_IMAGE
  2729                                  %if _PAYLOAD_KERNEL_MAX_PARAS
  2730                                  	mov cx, _PAYLOAD_KERNEL_MAX_PARAS
  2731                                  	mov bx, 0
  2732                                  %else
  2733 00000163 B92814                  	mov cx, payload_uncompressed_size >> 4
  2734 00000166 BB0000                  	mov bx, payload_uncompressed_size & 15
  2735                                  %endif
  2736 00000169 8CCF                    	mov di, cs
  2737 0000016B 83C739                  	add di, (payload_uncompressed - init2_start) >> 4
  2738 0000016E E319                    	jcxz .end
  2739                                  .loop:
  2740 00000170 51                      	push cx
  2741 00000171 B90800                  	mov cx, 8
  2742 00000174 8EDE                    	mov ds, si
  2743 00000176 8EC7                    	mov es, di
  2744 00000178 46                      	inc si
  2745 00000179 47                      	inc di
  2746 0000017A 56                      	push si
  2747 0000017B 57                      	push di
  2748 0000017C 31F6                    	xor si, si
  2749 0000017E 31FF                    	xor di, di
  2750 00000180 F3A7                    	repe cmpsw
  2751 00000182 5F                      	pop di
  2752 00000183 5E                      	pop si
  2753 00000184 59                      	pop cx
  2754 00000185 750E                    	jne .ret
  2755 00000187 E2E7                    	loop .loop
  2756                                  .end:
  2757 00000189 8EDE                    	mov ds, si
  2758 0000018B 8EC7                    	mov es, di
  2759 0000018D 31F6                    	xor si, si
  2760 0000018F 31FF                    	xor di, di		; (ZR)
  2761 00000191 89D9                    	mov cx, bx
  2762 00000193 F3A6                    	repe cmpsb
  2763                                  %else
  2764                                  %if _RELOAD_FILE
  2765                                  size_compressed_plus_uncompressed equ  payload_uncompressed_size + (payload.end - payload)
  2767                                  	mov cx, ((- size_compressed_plus_uncompressed) >> 16) & 0FFFFh
  2768                                  	mov dx, (- size_compressed_plus_uncompressed) & 0FFFFh
  2769                                  %else
  2770                                  	mov cx, ((- payload_uncompressed_size) >> 16) & 0FFFFh
  2771                                  	mov dx, (- payload_uncompressed_size) & 0FFFFh
  2772                                  %endif
  2773                                  	mov ax, 4202h
  2774                                  	mov bx, [bp + ?handle]
  2775                                  	int 21h
  2776                                  	jc .error
  2777                                  %if payload_uncompressed_size == 0
  2778                                   %error Empty payload not allowed
  2779                                  %endif
  2780                                  %if (payload_uncompressed_size / ?buffersize) != 0
  2781                                  	mov cx, payload_uncompressed_size / ?buffersize
  2782                                  %if ?buffersize == 0 || (?buffersize & 15) != 0
  2783                                   %error Unexpected layout
  2784                                  %endif
  2785                                  .loop:
  2786                                  	push cx
  2787                                  	mov cx, ?buffersize
  2788                                  	call comparechunk
  2789                                  	pop cx
  2790                                  	jne .ret
  2791                                  	loop .loop
  2792                                  %endif
  2793                                  %if (payload_uncompressed_size % ?buffersize) != 0
  2794                                  	mov cx, payload_uncompressed_size % ?buffersize
  2795                                  	call comparechunk
  2796                                  %endif
  2797                                  %endif
  2798                                  .ret:
  2799 00000195 5E                      	pop si
  2800 00000196 5A                      	pop dx
  2801 00000197 58                      	pop ax
  2802 00000198 C3                      	retn
  2803                                  
  2804                                  %if ! _INCLUDE_UNCOMPRESSED_IN_IMAGE
  2805                                  .error:
  2806                                  	or al, 1			; NZ
  2807                                  	jmp .ret
  2808                                  %endif
  2809                                  %endif
  2810                                  
  2811                                  
  2812                                  %if ! _INCLUDE_UNCOMPRESSED_IN_IMAGE
  2813                                  		; INP:	?buffer -> ?buffersize buffer
  2814                                  		;	cx = amount of bytes, 0 < cx <= ?buffersize
  2815                                  		;	si => chunk
  2816                                  		;	?handle = handle
  2817                                  		;	seek -> chunk
  2818                                  		; OUT:	NZ if mismatch or error
  2819                                  		;	ZR else,
  2820                                  		;	 si => next chunk (assumes full chunk)
  2821                                  		; CHG:	ds, es, di, ax, bx, cx, dx
  2822                                  		; STT:	UP
  2823                                  comparechunk:
  2824                                  	push ss
  2825                                  	pop ds
  2826                                  	lea dx, [bp + ?buffer]
  2827                                  	mov bx, [bp + ?handle]
  2828                                  	mov ah, 3Fh
  2829                                  	int 21h
  2830                                  	jc .error
  2831                                  	cmp ax, cx
  2832                                  	jne .error
  2833                                  	mov es, si
  2834                                  	add si, ?buffersize / 16
  2835                                  	push si
  2836                                  	xor di, di
  2837                                  	mov si, dx
  2838                                  	repe cmpsb
  2839                                  	pop si
  2840                                  .ret:
  2841                                  	retn
  2842                                  
  2843                                  .error:
  2844                                  	or al, 1			; NZ
  2845                                  	retn
  2846                                  %endif
  2847                                  
  2848                                  %if _RELOAD_XMS
  2849                                  freexms:
  2850                                  	push ax
  2851                                  	push bx
  2852                                  	push dx
  2853                                  	mov dx, -1
  2854                                  	xchg dx, [bp + ?xmshandle]
  2855                                  %if _RELOAD_FILE
  2856                                  	cmp dx, -1
  2857                                  	je @F
  2858                                  %endif
  2859                                  	mov ah, 0Ah
  2860                                  	call far [bp + ?xmsentry]
  2861                                  @@:
  2862                                  	pop dx
  2863                                  	pop bx
  2864                                  	pop ax
  2865                                  	retn
  2866                                  
  2867                                  init2_error_xms_free:
  2868                                  	call freexms
  2869                                  init2_error_xms:
  2870                                  	mov dx, init2_msg.xms_error
  2871                                  	mov cx, init2_msg.xms_error.length
  2872                                  	jmp init2_error
  2873                                  %endif
  2874                                  
  2875                                  %if _RELOAD_FILE
  2876                                  init2_error_file:
  2877                                  	mov dx, init2_msg.file_error
  2878                                  	mov cx, init2_msg.file_error.length
  2879                                  %endif
  2880                                  
  2881                                  init2_error_free:
  2882                                  %if _RELOAD_XMS
  2883                                  	call freexms
  2884                                  %endif
  2885                                  init2_error:
  2886                                  %if _DEBUG0
  2887                                  	push bx
  2888                                  %endif
  2889 00000199 0E                      	push cs
  2890 0000019A 1F                      	pop ds
  2891 0000019B BB0200                  	mov bx, 2
  2892 0000019E B440                    	mov ah, 40h
  2893 000001A0 CD21                    	int 21h
  2894                                  
  2895                                  %if _DEBUG0
  2896                                  	mov dx, init2_msg.rc
  2897                                  	mov cx, init2_msg.rc.length
  2898                                  	mov bx, 2
  2899                                  	mov ah, 40h
  2900                                  	int 21h
  2901                                  	pop ax
  2902                                  	call init2_error_disp_ax_hex
  2903                                  	mov dx, init2_msg.linebreak
  2904                                  	mov cx, init2_msg.linebreak.length
  2905                                  	mov bx, 2
  2906                                  	mov ah, 40h
  2907                                  	int 21h
  2908                                  %endif
  2909                                  
  2910 000001A2 F6460340                	testopt [bp + ?whichtest], 4000h
  2911 000001A6 7408                    	jz @F
  2912 000001A8 BA[FA02]                	mov dx, init2_msg.error_c_stdout
  2913 000001AB B90300                  	mov cx, init2_msg.error_c_stdout.length
  2914 000001AE EB0C                    	jmp @FF
  2915                                  @@:
  2916 000001B0 F6460380                	testopt [bp + ?whichtest], 8000h
  2917 000001B4 750D                    	jnz @FF
  2918 000001B6 BA[FA02]                	mov dx, init2_msg.error_stdout
  2919 000001B9 B90300                  	mov cx, init2_msg.error_stdout.length
  2920                                  @@:
  2921 000001BC BB0100                  	mov bx, 1
  2922 000001BF B440                    	mov ah, 40h
  2923 000001C1 CD21                    	int 21h
  2924                                  @@:
  2925 000001C3 B8FF4C                  	mov ax, 4CFFh
  2926 000001C6 CD21                    	int 21h
  2927                                  
  2928                                  	lleave ctx
  2929                                  
  2930                                  
  2931                                  %if _DEBUG0
  2932                                  init2_error_disp_ax_hex:	; ax
  2933                                  		xchg al,ah
  2934                                  		call init2_error_disp_al_hex	; display former ah
  2935                                  		xchg al,ah			;  and fall trough for al
  2936                                  init2_error_disp_al_hex:	; al
  2937                                  		push cx
  2938                                  		mov cl,4
  2939                                  		ror al,cl
  2940                                  		call init2_error_disp_al_lownibble_hex
  2941                                  						; display former high-nibble
  2942                                  		rol al,cl
  2943                                  		pop cx
  2944                                  						;  and fall trough for low-nibble
  2945                                  init2_error_disp_al_lownibble_hex:
  2946                                  		push ax			 ; save ax for call return
  2947                                  		and al,00001111b		; high nibble must be zero
  2948                                  		add al,'0'			; if number is 0-9, now it's the correct character
  2949                                  		cmp al,'9'
  2950                                  		jna .decimalnum		 ; if we get decimal number with this, ok -->
  2951                                  		add al,7			;  otherwise, add 7 and we are inside our alphabet
  2952                                   .decimalnum:
  2953                                  		call init2_error_disp_al
  2954                                  		pop ax
  2955                                  		retn
  2956                                  
  2957                                  
  2958                                  init2_error_disp_al:
  2959                                  	push dx
  2960                                  	push cx
  2961                                  	push bx
  2962                                  	push ax
  2963                                  	mov dx, sp
  2964                                  	push ds
  2965                                  	 push ss
  2966                                  	 pop ds
  2967                                  	mov cx, 1
  2968                                  	mov bx, 2
  2969                                  	mov ah, 40h
  2970                                  	int 21h
  2971                                  	pop ds
  2972                                  	pop ax
  2973                                  	pop bx
  2974                                  	pop cx
  2975                                  	pop dx
  2976                                  	retn
  2977                                  %endif
  2978                                  
  2979                                  
  2980                                  init2_disp_al:
  2981 000001C8 52                      	push dx
  2982 000001C9 50                      	push ax
  2983 000001CA 88C2                    	mov dl, al
  2984 000001CC B402                    	mov ah, 2
  2985 000001CE CD21                    	int 21h
  2986 000001D0 58                      	pop ax
  2987 000001D1 5A                      	pop dx
  2988 000001D2 C3                      	retn
  2989                                  
  2990                                  
  2991                                  		; Display number in ax decimal
  2992                                  		;
  2993                                  		; INP:	ax = number
  2994                                  		; OUT:	displayed using Int21.02
  2995                                  		; CHG:	none
  2996                                  init2_disp_ax_dec:			; ax (no leading zeros)
  2997 000001D3 53                      		push bx
  2998 000001D4 31DB                    		xor bx, bx
  2999                                  .pushax:
  3000 000001D6 52                      		push dx
  3001 000001D7 50                      		push ax
  3002 000001D8 08DB                    		or bl, bl
  3003 000001DA 7405                    		jz .nobl
  3004 000001DC 80EB05                  		sub bl, 5
  3005 000001DF F6DB                    		neg bl
  3006                                  .nobl:
  3007 000001E1 51                      		push cx
  3008 000001E2 B91027                  		mov cx, 10000
  3009 000001E5 E81B00                  		call .divide_out
  3010 000001E8 B9E803                  		mov cx, 1000
  3011 000001EB E81500                  		call .divide_out
  3012 000001EE B96400                  		mov cx, 100
  3013 000001F1 E80F00                  		call .divide_out
  3014 000001F4 B10A                    		mov cl, 10
  3015 000001F6 E80A00                  		call .divide_out
  3016                                  							; (Divisor 1 is useless)
  3017 000001F9 0430                    		add al, '0'
  3018 000001FB E8CAFF                  		call init2_disp_al
  3019 000001FE 59                      		pop cx
  3020 000001FF 58                      		pop ax
  3021 00000200 5A                      		pop dx
  3022 00000201 5B                      		pop bx					; Caller's register
  3023 00000202 C3                      		retn
  3024                                  
  3025                                  
  3026                                  		; INP:	ax = number
  3027                                  		;	cx = divisor
  3028                                  		; OUT:	ax = remainder of operation
  3029                                  		;	result displayed
  3030                                  .divide_out:
  3031 00000203 52                      		push dx
  3032 00000204 31D2                    		xor dx, dx
  3033 00000206 F7F1                    		div cx				; 0:ax / cx
  3034 00000208 52                      		push dx				; remainder
  3035 00000209 FECB                    		dec bl
  3036 0000020B 7503                    		jnz .nobl2
  3037 0000020D 80CF01                  		or bh, 1
  3038                                  .nobl2:
  3039 00000210 08C7                    		or bh, al
  3040 00000212 7405                    		jz .leadingzero
  3041 00000214 0430                    		add al, '0'
  3042 00000216 E8AFFF                  		call init2_disp_al		; display result
  3043                                   .leadingzero:
  3044 00000219 58                      		pop ax				; remainder
  3045 0000021A 5A                      		pop dx
  3046 0000021B C3                      		retn
  3047                                  
  3048                                  
  3049                                  init2_msg:
  3050                                  %if _TEST_PROGRESS
  3051 0000021C 496E666F3A2031          .progress.1:		db "Info: 1"
  3052                                  .progress.1.length: equ $ - .progress.1
  3053 00000223 46                      .progress.fail:		db "F"
  3054                                  .progress.fail.length: equ $ - .progress.fail
  3055 00000224 53                      .progress.success:	db "S"
  3056                                  .progress.success.length: equ $ - .progress.success
  3057 00000225 0D0A                    .progress.linebreak:	db 13,10
  3058                                  .progress.linebreak.length: equ $ - .progress.linebreak
  3059                                  %endif
  3060                                  %if _WRITE_WRONG_FILE
  3061                                  .wrong_file_name:	asciz "WRONG.BIN"
  3062                                  .wrong_file_name2:	asciz "WRONG2.BIN"
  3063                                  %endif
  3064 00000227 4572726F723A205465-     .initial_error:	db "Error: Test program failed to decompress with full buffer."
  3064 00000230 73742070726F677261-
  3064 00000239 6D206661696C656420-
  3064 00000242 746F206465636F6D70-
  3064 0000024B 726573732077697468-
  3064 00000254 2066756C6C20627566-
  3064 0000025D 6665722E           
  3065 00000261 0D0A                    .linebreak:	db 13,10
  3066                                  .initial_error.length: equ $ - .initial_error
  3067                                  .linebreak.length: equ $ - .linebreak
  3068                                  %if _DEBUG0
  3069                                  .rc:	db "Error: Failure code="
  3070                                  .rc.length: equ $ - .rc
  3071                                  %endif
  3072                                  %if _INCLUDE_UNCOMPRESSED
  3073 00000263 4572726F723A205465-     .initial_error_2:	db "Error: Test program decompressed wrongly with full buffer.",13,10
  3073 0000026C 73742070726F677261-
  3073 00000275 6D206465636F6D7072-
  3073 0000027E 65737365642077726F-
  3073 00000287 6E676C792077697468-
  3073 00000290 2066756C6C20627566-
  3073 00000299 6665722E0D0A       
  3074                                  .initial_error_2.length: equ $ - .initial_error_2
  3075 0000029F 4572726F723A205465-     .subsequent_error_2:	db "Error: Test program decompressed wrongly during test.",13,10
  3075 000002A8 73742070726F677261-
  3075 000002B1 6D206465636F6D7072-
  3075 000002BA 65737365642077726F-
  3075 000002C3 6E676C792064757269-
  3075 000002CC 6E6720746573742E0D-
  3075 000002D5 0A                 
  3076                                  .subsequent_error_2.length: equ $ - .subsequent_error_2
  3077                                  %endif
  3078 000002D6 4572726F723A20496E-     .cmdline_error:	db "Error: Invalid command line input.",13,10
  3078 000002DF 76616C696420636F6D-
  3078 000002E8 6D616E64206C696E65-
  3078 000002F1 20696E7075742E0D0A 
  3079                                  .cmdline_error.length: equ $ - .cmdline_error
  3080                                  %if _RELOAD_XMS
  3081                                  .xms_error:	db "Error: XMS failure.",13,10
  3082                                  .xms_error.length: equ $ - .xms_error
  3083                                  %endif
  3084                                  %if _RELOAD_FILE
  3085                                  .file_error:	db "Error: File read failure.",13,10
  3086                                  .file_error.length: equ $ - .file_error
  3087                                  %endif
  3088                                  
  3089                                  .error_c_stdout:
  3090 000002FA 30                      .error_stdout:	db "0"
  3091                                  %if 0
  3092                                  		_autodigits paras(_TEST_PROGRAM_DECOMPRESSED_SIZE 				+ (payload_end - payload) 				+ (init1_end - init1_start) 				+ ADDITIONAL_MEMORY 				)
  3097                                  %endif
  3098 000002FB 0D0A                    		db 13,10
  3099                                  .error_c_stdout.length: equ $ - .error_c_stdout
  3100                                  .error_stdout.length: equ $ - .error_stdout
  3101                                  
  3102                                  
  3103                                  		; Move paragraphs
  3104                                  		;
  3105                                  		; INP:	ax => source
  3106                                  		;	dx => destination
  3107                                  		;	cx = number of paragraphs
  3108                                  		; CHG:	-
  3109                                  		; OUT:	ax and dx unchanged
  3110                                  		; Note:	Doesn't work correctly on HMA; doesn't always wrap to LMA either.
  3111                                  		;	Do not provide a wrapped/HMA source or destination!
  3112                                  init2_movp:
  3113 000002FD 51                      	push cx
  3114 000002FE 1E                      	push ds
  3115 000002FF 56                      	push si
  3116 00000300 06                      	push es
  3117 00000301 57                      	push di
  3118                                  
  3119 00000302 39D0                    	cmp ax, dx		; source above destination ?
  3120 00000304 770A                    	ja .up			; yes, move up (forwards) -->
  3121 00000306 747B                    	je .return		; same, no need to move -->
  3122 00000308 50                      	push ax
  3123 00000309 01C8                    	add ax, cx		; (expected not to carry)
  3124 0000030B 39D0                    	cmp ax, dx		; end of source is above destination ?
  3125 0000030D 58                      	pop ax
  3126 0000030E 7730                    	ja .down		; yes, move from top down -->
  3127                                  	; Here, the end of source is below-or-equal the destination,
  3128                                  	;  so they do not overlap. In this case we prefer moving up.
  3129                                  
  3130                                  .up:
  3131 00000310 50                      	push ax
  3132 00000311 52                      	push dx
  3133                                  .uploop:
  3134 00000312 8ED8                    	mov ds, ax
  3135 00000314 8EC2                    	mov es, dx
  3136 00000316 31FF                    	xor di, di
  3137 00000318 31F6                    	xor si, si		; -> start of segment
  3138 0000031A 81E90010                	sub cx, 1000h		; 64 KiB left ?
  3139 0000031E 7610                    	jbe .uplast		; no -->
  3140 00000320 51                      	push cx
  3141 00000321 B90080                  	mov cx, 10000h /2
  3142 00000324 F3A5                    	rep movsw		; move 64 KiB
  3143 00000326 59                      	pop cx
  3144 00000327 050010                  	add ax, 1000h
  3145 0000032A 81C20010                	add dx, 1000h		; -> next segment
  3146 0000032E EBE2                    	jmp short .uploop	; proceed for more -->
  3147                                  .uplast:
  3148 00000330 81C10010                	add cx, 1000h		; restore counter
  3149 00000334 D1E1                    	shl cx, 1
  3150 00000336 D1E1                    	shl cx, 1
  3151 00000338 D1E1                    	shl cx, 1		; *8, paragraphs to words
  3152 0000033A F3A5                    	rep movsw		; move last part
  3153 0000033C 5A                      	pop dx
  3154 0000033D 58                      	pop ax
  3155 0000033E EB43                    	jmp short .return
  3156                                  
  3157                                  .down:
  3158 00000340 FD                      	std			; _AMD_ERRATUM_109_WORKAROUND as below
  3159                                  .dnloop:
  3160 00000341 81E90010                	sub cx, 1000h		; 64 KiB left ?
  3161 00000345 761A                    	jbe .dnlast		; no -->
  3162 00000347 50                      	push ax
  3163 00000348 52                      	push dx
  3164 00000349 01C8                    	add ax, cx
  3165 0000034B 01CA                    	add dx, cx
  3166 0000034D 8ED8                    	mov ds, ax		; -> 64 KiB not yet moved
  3167 0000034F 8EC2                    	mov es, dx
  3168 00000351 5A                      	pop dx
  3169 00000352 58                      	pop ax
  3170 00000353 BFFEFF                  	mov di, -2
  3171 00000356 89FE                    	mov si, di		; moved from last word down
  3172 00000358 51                      	push cx
  3173 00000359 B90080                  	mov cx, 10000h /2
  3174 0000035C F3A5                    	rep movsw		; move 64 KiB
  3175 0000035E 59                      	pop cx
  3176 0000035F EBE0                    	jmp short .dnloop	; proceed for more -->
  3177                                  .dnlast:
  3178 00000361 81C10010                	add cx, 1000h		; restore counter
  3179 00000365 D1E1                    	shl cx, 1
  3180 00000367 D1E1                    	shl cx, 1
  3181 00000369 D1E1                    	shl cx, 1		; *8, paragraphs to words
  3182 0000036B 89CF                    	mov di, cx
  3183 0000036D 4F                      	dec di
  3184 0000036E D1E7                    	shl di, 1		; words to offset, -> last word
  3185 00000370 89FE                    	mov si, di
  3186 00000372 8ED8                    	mov ds, ax
  3187 00000374 8EC2                    	mov es, dx		; first segment correct
  3188                                  
  3189                                  		; Refer to comment in init0_movp.
  3190                                  %if _AMD_ERRATUM_109_WORKAROUND
  3191 00000376 E308                    	jcxz @FF
  3192 00000378 83F914                  	cmp cx, 20
  3193 0000037B 7703                    	ja @FF
  3194                                  @@:
  3195 0000037D A5                      	movsw
  3196 0000037E E2FD                    	loop @B
  3197                                  @@:
  3198                                  %endif
  3199 00000380 F3A5                    	rep movsw		; move first part
  3200 00000382 FC                      	cld
  3201                                  .return:
  3202 00000383 5F                      	pop di
  3203 00000384 07                      	pop es
  3204 00000385 5E                      	pop si
  3205 00000386 1F                      	pop ds
  3206 00000387 59                      	pop cx
  3207 00000388 C3                      	retn
  3208                                  
  3209                                  
  3210 00000389 90<rep 3h>              	align 4
  3211                                  %if _RELOAD_XMS
  3212                                  init2_xmsm_from_save:
  3213                                  	istruc XMSM
  3214                                  at XMSM.size_,	dd payload_end - payload
  3215                                  	iend
  3216                                  init2_xmsm_to_save:
  3217                                  	istruc XMSM
  3218                                  at XMSM.size_,	dd payload_end - payload
  3219                                  	iend
  3220                                  %endif
  3221                                  
  3222 0000038C 90<rep 4h>              	align 16
  3223                                  
  3224                                  %if _INCLUDE_UNCOMPRESSED && _INCLUDE_UNCOMPRESSED_IN_IMAGE
  3225                                  	strdef UNCOMPRESSED_FILE, "lDOSLOAD.BIN"
  3226                                  payload_uncompressed:
  3227 00000390 <bin 14280h>            	incbin _UNCOMPRESSED_FILE
  3228                                  .end:
  3229 00014610 26                      	db 38
  3230 00014611 26<rep Fh>              	align 16, db 38
  3231                                  %endif
  3232                                  init2_end:
  3233                                  %endif
  3234                                  
