
=== Trace listing source: combxms.lst
     1                                  
     2                                  %if 0
     3                                  
     4                                  lDOS COMLOADER - load embedded programs
     5                                   by E. C. Masloch, 2018--2025
     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                                  Parts copied from msdos4/src/CMD/DEBUG/DEBCOM2.ASM and
    14                                  msdos4/src/CMD/DEBCOM3.ASM (under MIT license).
    15                                  
    16                                  %endif
    17                                  
    18                                  	cpu 8086
    19                                  
    20                                  %include "lmacros3.mac"
     1                              <1> [list -]
    14                              <2> [list -]
    14                              <1> [list -]
    21                                  %include "mzheader.mac"
     1                              <1> 
     2                              <1> %if 0
     3                              <1> 
     4                              <1> lDebug MZ .EXE header macros
     5                              <1> 
     6                              <1> Copyright (C) 1995-2003 Paul Vojta
     7                              <1> Copyright (C) 2008-2023 E. C. Masloch
     8                              <1> 
     9                              <1> Usage of the works is permitted provided that this
    10                              <1> instrument is retained with the works, so that any entity
    11                              <1> that uses the works is notified of this instrument.
    12                              <1> 
    13                              <1> DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
    14                              <1> 
    15                              <1> %endif
    16                              <1> 
    17                              <1> 
    18                              <1> 	struc EXEHEADER
     0 00000000 ????                    exact_struc_at 00h, exeSignature:	resw 1
     0 00000002 ????                    exact_struc_at 02h, exeExtraBytes:	resw 1	; bytes in last page
     0 00000004 ????                    exact_struc_at 04h, exePages:		resw 1	; number of 512-byte pages. includes the header!
     0 00000006 ????                    exact_struc_at 06h, exeRelocItems:	resw 1	; number of relocation items
     0 00000008 ????                    exact_struc_at 08h, exeHeaderSize:	resw 1	; header size in 16-byte paragraphs
     0 0000000A ????                    exact_struc_at 0Ah, exeMinAlloc:	resw 1	; minimum (bss) allocation in paragraphs
     0 0000000C ????                    exact_struc_at 0Ch, exeMaxAlloc:	resw 1	; maximum (bss) allocation in paragraphs
     0 0000000E ????                    exact_struc_at 0Eh, exeInitSS:		resw 1	; init ss (is relocated)
     0 00000010 ????                    exact_struc_at 10h, exeInitSP:		resw 1	; init sp
     0 00000012 ????                    exact_struc_at 12h, exeChecksum:	resw 1
    29                              <1> exact_struc_at 14h, exeInitCSIP:
     0 00000014 ????                    exact_struc_at 14h, exeInitIP:		resw 1	; init ip
     0 00000016 ????                    exact_struc_at 16h, exeInitCS:		resw 1	; init cs (is relocated)
     0 00000018 ????                    exact_struc_at 18h, exeRelocTable:	resw 1	; byte offset of relocation table
    33                              <1> 		; Each relocation item is a word offset and a word segment.
    34                              <1> 		;  The segment of the item itself is relocated as well.
     0 0000001A ????                    exact_struc_at 1Ah, exeOverlayNum:	resw 1
    36                              <1> exact_struc_at 1Ch
    37                              <1> 	endstruc
    22                                  
    23                                  
    24                                  	numdef MZEXESUPPORT, 1
    25                                  	strdef DEVICEPAYLOAD, "srdmulti.sys"
    26                                  
=== Switch to base=000000h -> "DEVICE"
    27                                  addsection DEVICE
    28                                  device:
    29 00000000 <bin D71h>              	incbin _DEVICEPAYLOAD
     0 00000D71 26<rep Fh>              	align 16, db 38
    31                                  	endarea device
    32                                  
    33                                  %assign DEVICESIZE device_size
    34                                  %warning devicesize=%[DEVICESIZE]
    34          ******************       warning: devicesize=3456 [-w+user]
    35                                  
    36                                  
=== Switch to base=000D80h -> "PAYLOADFIRST"
    37                                  addsection PAYLOADFIRST, align=16
    38                                  payload1:
    39 00000000 <bin A000h>             	incbin "srdiskc.exe",0,40*1024
    40                                  	endarea payload1
    41                                  
=== Switch to base=00AD80h -> "PAYLOADSECOND"
    42                                  addsection PAYLOADSECOND, align=16
    43                                  payload2:
    44 00000000 <bin 6140h>             	incbin "srdiskc.exe",40*1024
    45                                  	align 16, db 38
    46                                  	endarea payload2
    47                                  
    48                                  payload_size equ payload1_size + payload2_size
    49                                  	endarea payload, 1
    50                                  
    51                                  %assign PAYLOADSIZE payload_size
    52                                  %warning payloadsize=%[PAYLOADSIZE]
    52          ******************       warning: payloadsize=65856 [-w+user]
    53                                  
    54                                  
=== Switch to base=010EC0h -> "COMLOADER"
    55                                  addsection COMLOADER, align=16
    56                                  ..start:
    57                                  COMLOADER_start:
    58                                  		; INP:	ds = es = PSP
    59                                  		;	cs:ip = COMLOADER segment : 0
    60                                  		;	ss:sp -> stack behind COMLOADER
    61                                  %if _MZEXESUPPORT
     0 00000000 EB0A                    	jmp @F
    63                                  relocatecomloader: equ $
     0 00000002 F3A5                    	rep movsw		; move downwards
     0 00000004 06                      	push es
     0 00000005 E80300                  	call .retf		; relocate
     0 00000008 E9D800                  	jmp donerelocatedcomloader
    68                                  				; continue at relocated comloader
    69                                  .retf:
     0 0000000B CB                      	retf
    71                                  
    72                                  %if ($ - relocatecomloader) > 16
    73                                   %error Relocate comloader is too large
    74                                  %endif
    75                                  
    76                                  
    77                                  @@:
     0 0000000C 50                      	push ax			; pass through ax
    79                                  %endif
     0 0000000D B91410                  	mov cx, payload_size_p
     0 00000010 B8[0000]                	mov ax, PAYLOADFIRST
    82                                  
    83                                  %if _MZEXESUPPORT
     0 00000013 8CC2                    	mov dx, es
     0 00000015 83C210                  	add dx, 10h		; => behind PSP
     0 00000018 E86001                  	call movp
    87                                  
     0 0000001B 8EDA                    	mov ds, dx		; => at MZ exe header if any
     0 0000001D 31DB                    	xor bx, bx		; -> at header
     0 0000001F 813F4D5A                	cmp word [bx + exeSignature], "MZ"
     0 00000023 7409                    	je .load_exe
     0 00000025 813F5A4D                	cmp word [bx + exeSignature], "ZM"
     0 00000029 7403E9FA00              	jne .load_com
    94                                  .load_exe:
     0 0000002E 06                      	push es
     0 0000002F 8B4F06                  	mov cx, word [bx + exeRelocItems]
     0 00000032 1E                      	push ds
     0 00000033 E327                    	jcxz .donereloc
     0 00000035 8B7718                  	mov si, word [bx + exeRelocTable]
   100                                  				; ds:si -> reloc table
   101                                  				;  (may overflow 64 KiB but starts within first)
     0 00000038 89D5                    	mov bp, dx
     0 0000003A 036F08                  	add bp, word [bx + exeHeaderSize]
   104                                  				; bp => exe image (after header)
   105                                  .loopreloc:
     0 0000003D 89F0                    	mov ax, si		; preserve upper 12 bits
     0 0000003F 83E60F                  	and si, 15		; isolate low 4 bits
     0 00000042 D1E8                    	shr ax, 1
     0 00000044 D1E8                    	shr ax, 1
     0 00000046 D1E8                    	shr ax, 1
     0 00000048 D1E8                    	shr ax, 1		; divide by 16
     0 0000004A 8CDF                    	mov di, ds
     0 0000004C 01C7                    	add di, ax		; => normalised relocation table entry
     0 0000004E 8EDF                    	mov ds, di
     0 00000050 AD                      	lodsw			; load offset
     0 00000051 97                      	xchg di, ax		; di = offset
     0 00000052 AD                      	lodsw			; load segment
     0 00000053 01E8                    	add ax, bp		; => relocation entry in exe image (after header)
     0 00000055 8EC0                    	mov es, ax		; es:di -> relocation entry
     0 00000057 260115                  	add word [es:di], dx	; relocate (with dx => behind PSP)
     0 0000005A E2E1                    	loop .loopreloc		; loop for all relocations
   122                                  .donereloc:
     0 0000005C 1F                      	pop ds			; => exe header
     0 0000005D 8B6F04                  	mov bp, word [bx + exePages]
     0 00000060 B105                    	mov cl, 5
     0 00000062 D3E5                    	shl bp, cl		; = how many paragraphs in header + image
     0 00000064 8B4708                  	mov ax, word [bx + exeHeaderSize]
     0 00000067 29C5                    	sub bp, ax		; = how many paragraphs in image
     0 00000069 7703E9D400              	jbe error_format
   130                                  		; lMS-DOS doesn't ever use exeExtraBytes.
   131                                  		;  we can ignore it likewise.
     0 0000006E 89E9                    	mov cx, bp
     0 00000070 01D0                    	add ax, dx		; => exe image
     0 00000072 7303E9CB00              	jc error_format
     0 00000077 07                      	pop es			; => PSP
     0 00000078 015716                  	add word [bx + exeInitCS], dx
     0 0000007B 01570E                  	add word [bx + exeInitSS], dx
   138                                  		; on stack: original ax
     0 0000007E FF7716                  	push word [bx + exeInitCS]
     0 00000081 FF7714                  	push word [bx + exeInitIP]
     0 00000084 FF770E                  	push word [bx + exeInitSS]
     0 00000087 FF7710                  	push word [bx + exeInitSP]
     0 0000008A FF770A                  	push word [bx + exeMinAlloc]
     0 0000008D FF770C                  	push word [bx + exeMaxAlloc]
     0 00000090 E8E800                  	call movp
   146                                  
     0 00000093 01CA                    	add dx, cx		; => behind exe image at destination
     0 00000095 7303E9A800              	jc error_format
     0 0000009A 5B                      	pop bx			; max alloc
     0 0000009B 58                      	pop ax			; min alloc
     0 0000009C 39D8                    	cmp ax, bx		; minimum > maximum ?
     0 0000009E 7603E99F00              	ja error_format
     0 000000A3 85DB                    	test bx, bx		; maximum == 0 ?
     0 000000A5 7503E99800              	jz error_format		; not supported -->
     0 000000AA 01CB                    	add bx, cx		; bx = maximum allocation size (maxalloc + image)
     0 000000AC 7205                    	jc .unlimited
     0 000000AE 83C310                  	add bx, 10h		; account for PSP
     0 000000B1 7303                    	jnc @F
   159                                  .unlimited:
     0 000000B3 BBFFFF                  	mov bx, -1		; if maximum requested, pass along bx = 0FFFFh
   161                                  @@:
     0 000000B6 01C2                    	add dx, ax		; dx => behind minimum allocation
     0 000000B8 7303E98500              	jc error_format
   164                                  
     0 000000BD 06                      	push es			; preserve => PSP
     0 000000BE 8CC8                    	mov ax, cs
     0 000000C0 39D0                    	cmp ax, dx
     0 000000C2 7320                    	jae .noreloc
     0 000000C4 8CD1                    	mov cx, ss
     0 000000C6 83E928                  	sub cx, paras(COMLOADER_end - COMLOADER_start)
     0 000000C9 39C8                    	cmp ax, cx
     0 000000CB 7370                    	jae error_memory
     0 000000CD 39D1                    	cmp cx, dx
     0 000000CF 7271                    	jb error_format
     0 000000D1 8EC1                    	mov es, cx		; => comloader destination
     0 000000D3 0E                      	push cs
     0 000000D4 1F                      	pop ds			; => comloader source
     0 000000D5 B94001                  	mov cx, words(COMLOADER_end - COMLOADER_start)
     0 000000D8 89CE                    	mov si, cx		; = amount words
     0 000000DA 01F6                    	add si, si		; = amount bytes
     0 000000DC 89F7                    	mov di, si		; -> after last byte to move
     0 000000DE FD                      	std
     0 000000DF A7                      	cmpsw			; -> at last word to move
     0 000000E0 E91FFF                  	jmp relocatecomloader	; do rep movsw and far branch to relocated
   185                                  
   186                                  donerelocatedcomloader: equ $	; returns control flow here from relocator
     0 000000E3 FC                      	cld			; UP !
   188                                  .noreloc:
     0 000000E4 58                      	pop ax			; ax => PSP
   190                                  				; bx = requested maximum allocation size
   191                                  
     0 000000E5 5F                      	pop di
     0 000000E6 5D                      	pop bp			; bp:di = stack
   194                                  
     0 000000E7 0E                      	push cs
     0 000000E8 1F                      	pop ds
     0 000000E9 BE[1601]                	mov si, .enterstub	; -> stub source
     0 000000EC 8F4402                  	pop word [si + .enterstub_ip]
     0 000000EF 8F4404                  	pop word [si + .enterstub_cs]
   200                                  				; set cs:ip
     0 000000F2 8F04                    	pop word [si + .enterstub_ax]
   202                                  				; set ax (from our entrypoint)
   203                                  
     0 000000F4 8EC5                    	mov es, bp		; => stack destination
   205                                  %if 0
   206                                  	test di, di		; sp = 0 ?
   207                                  	jnz @F
   208                                  	dec di
   209                                  	dec di			; yes, allocate 1 word on the stack
   210                                  		; This cures a crash on dosemu2 that occurs if
   211                                  		;  the retf 000Ch instruction is placed directly
   212                                  		;  at the end of a segment (starting on offset
   213                                  		;  0FFFDh extending below 10000h). Refer to
   214                                  		;  https://github.com/dosemu2/dosemu2/issues/2575
   215                                  @@:
   216                                  %endif
     0 000000F6 B91200                  	mov cx, .enterstub_size_w * 2
     0 000000F9 29CF                    	sub di, cx		; -> space for stub
     0 000000FB D1E9                    	shr cx, 1		; = amount words
     0 000000FD 57                      	 push di
     0 000000FE F3A5                    	rep movsw		; place stub
     0 00000100 5F                      	 pop di			; bp:di -> stub
     0 00000101 8EC0                    	mov es, ax		; es => PSP
     0 00000103 8ED8                    	mov ds, ax		; ds => PSP
     0 00000105 FA                      	cli
     0 00000106 8ED5                    	mov ss, bp
     0 00000108 89FC                    	mov sp, di		; relocate stack
     0 0000010A FB                      	sti
     0 0000010B 8D4506                  	lea ax, [di + .enterstub_entry]	; ss:ax -> stub entry
     0 0000010E 16                      	push ss
     0 0000010F 50                      	push ax			; -> stub's entry on stack
     0 00000110 BF0200                  	mov di, 2		; es:di -> PSP word at [2]
     0 00000113 B44A                    	mov ah, 4Ah		; ah = 4Ah
     0 00000115 CB                      	retf			; branch to there
   235                                  
   236                                  	align 2, nop
   237                                  .enterstub:
   238                                  .enterstub_ax: equ $ - .enterstub
     0 00000116 0000                    	dw 0
   240                                  .enterstub_ip: equ $ - .enterstub
     0 00000118 0000                    	dw 0
   242                                  .enterstub_cs: equ $ - .enterstub
     0 0000011A 0000                    	dw 0
   244                                  
   245                                  		; INP:	es = ds => PSP
   246                                  		;	bx = maximum allocation size
   247                                  		;	MCB already >= minimum allocation size
   248                                  		;	ah = 4Ah
   249                                  		;	di = 2
   250                                  		;	ss:sp -> stack with ax, ip, cs, stub
   251                                  .enterstub_entry: equ $ - .enterstub
     0 0000011C CD21                    	int 21h
     0 0000011E 8CC0                    	mov ax, es		; => PSP
     0 00000120 01D8                    	add ax, bx		; => behind allocation
     0 00000122 AB                      	stosw			; store in word [PSP:2]
     0 00000123 58                      	pop ax			; pass through ax
     0 00000124 CA0C00                  	retf .enterstub_size - 6; branch to entry and pop off the enterstub
     0 00000127 90                      	nop	; Better cure for https://github.com/dosemu2/dosemu2/issues/2575
   259                                  	align 2, nop
   260                                  	endarea .enterstub
   261                                  
   262                                  .load_com:
   263                                  %else
   264                                  	mov ds, ax
   265                                  	xor si, si		; ds:si -> source
   266                                  
   267                                  %if 01
   268                                  	cmp word [si + exeSignature], "MZ"
   269                                  	je error_mz_exe_not_supported
   270                                  	cmp word [si + exeSignature], "ZM"
   271                                  	je error_mz_exe_not_supported
   272                                  %endif
   273                                  
   274                                  	push di
   275                                  	rep movsw		; move to behind PSP
   276                                  %endif
   277                                  
     0 00000128 8CC7                    	mov di, es
     0 0000012A 81C70010                	add di, 1000h		; => behind area to be used by stack
     0 0000012E 8CC8                    	mov ax, cs		; => COMLOADER segment
     0 00000130 39F8                    	cmp ax, di		; COMLOADER starts above-or-equal stack end ?
     0 00000132 7313                    	jae @F
   283                                  
     0 00000134 8CD0                    	mov ax, ss
     0 00000136 83E802                  	sub ax, .to_reloc_size_p
     0 00000139 39F8                    	cmp ax, di
     0 0000013B 731E                    	jae .reloc
   288                                  
   289                                  error_memory: equ $
     0 0000013D BA[0702]                	mov dx, msg.internal_error_memory
     0 00000140 EB2E                    	jmp .error_exit
   292                                  
   293                                  %if _MZEXESUPPORT
   294                                  error_format: equ $
     0 00000142 BA[4202]                	mov dx, msg.internal_error_format
     0 00000145 EB29                    	jmp .error_exit
   297                                  %elif 01
   298                                  error_mz_exe_not_supported: equ $
   299                                  	mov dx, msg.internal_error_mz
   300                                  	jmp .error_exit
   301                                  %endif
   302                                  
   303                                  @@:
   304                                  .to_reloc:
   305                                  %if _MZEXESUPPORT
     0 00000147 BF0001                  	mov di, 100h
   307                                  %else
   308                                  	pop di
   309                                  %endif
     0 0000014A 58                      	pop ax			; preserve original ax
   311                                  
     0 0000014B 06                      	push es
     0 0000014C FA                      	cli
     0 0000014D 17                      	pop ss
     0 0000014E 31E4                    	xor sp, sp		; full 64 KiB's stack
     0 00000150 FB                      	sti
     0 00000151 31F6                    	xor si, si		; si = 0
     0 00000153 56                      	push si			; 0 word on stack
   319                                  
     0 00000154 06                      	 push es
     0 00000155 1F                      	 pop ds			; ds = es = ss = cs = PSP
   322                                  
     0 00000156 8CC9                    	mov cx, cs		; => name table
   324                                  
     0 00000158 06                      	push es
     0 00000159 57                      	push di			; -> PSP : 256
     0 0000015A CB                      	retf
   328                                  	endarea .to_reloc
   329                                  
   330                                  
   331                                  .reloc:
     0 0000015B 06                      	push es
     0 0000015C 8EC0                    	mov es, ax
     0 0000015E 31FF                    	xor di, di
     0 00000160 B91000                  	mov cx, words(fromparas(.to_reloc_size_p))
     0 00000163 0E                      	push cs
     0 00000164 1F                      	pop ds
     0 00000165 BE[4701]                	mov si, .to_reloc
     0 00000168 F3A5                    	rep movsw
     0 0000016A 89DE                    	mov si, bx
     0 0000016C 07                      	pop es
     0 0000016D 50                      	push ax
     0 0000016E 51                      	push cx
     0 0000016F CB                      	retf
   345                                  
   346                                  
   347                                  .error_exit:
     0 00000170 0E                      	push cs
     0 00000171 1F                      	pop ds
     0 00000172 B409                    	mov ah, 09h
     0 00000174 CD21                    	int 21h
     0 00000176 B8014C                  	mov ax, 4C01h
     0 00000179 CD21                    	int 21h
   354                                  
   355                                  
   356                                  %if _MZEXESUPPORT
   357                                  		; Move paragraphs
   358                                  		;
   359                                  		; INP:	ax:0-> source
   360                                  		;	dx:0-> destination
   361                                  		;	cx = number of paragraphs
   362                                  		; CHG:	-
   363                                  		; Note:	Doesn't work correctly on HMA; doesn't always wrap to LMA either.
   364                                  		;	Do not provide a wrapped/HMA source or destination!
   365                                  movp:
     0 0000017B 51                      	push cx
     0 0000017C 1E                      	push ds
     0 0000017D 56                      	push si
     0 0000017E 06                      	push es
     0 0000017F 57                      	push di
   371                                  
     0 00000180 39D0                    	cmp ax, dx		; source above destination ?
     0 00000182 770A                    	ja .up			; yes, move up (forwards) -->
     0 00000184 747B                    	je .return		; same, no need to move -->
     0 00000186 50                      	push ax
     0 00000187 01C8                    	add ax, cx		; (expected not to carry)
     0 00000189 39D0                    	cmp ax, dx		; end of source is above destination ?
     0 0000018B 58                      	pop ax
     0 0000018C 7730                    	ja .down		; yes, move from top down -->
   380                                  	; Here, the end of source is below-or-equal the destination,
   381                                  	;  so they do not overlap. In this case we prefer moving up.
   382                                  
   383                                  .up:
     0 0000018E 50                      	push ax
     0 0000018F 52                      	push dx
   386                                  .uploop:
     0 00000190 8ED8                    	mov ds, ax
     0 00000192 8EC2                    	mov es, dx
     0 00000194 31FF                    	xor di, di
     0 00000196 31F6                    	xor si, si		; -> start of segment
     0 00000198 81E90010                	sub cx, 1000h		; 64 KiB left ?
     0 0000019C 7610                    	jbe .uplast		; no -->
     0 0000019E 51                      	push cx
     0 0000019F B90080                  	mov cx, 10000h /2
     0 000001A2 F3A5                    	rep movsw		; move 64 KiB
     0 000001A4 59                      	pop cx
     0 000001A5 050010                  	add ax, 1000h
     0 000001A8 81C20010                	add dx, 1000h		; -> next segment
     0 000001AC EBE2                    	jmp short .uploop	; proceed for more -->
   400                                  .uplast:
     0 000001AE 81C10010                	add cx, 1000h		; restore counter
     0 000001B2 D1E1                    	shl cx, 1
     0 000001B4 D1E1                    	shl cx, 1
     0 000001B6 D1E1                    	shl cx, 1		; *8, paragraphs to words
     0 000001B8 F3A5                    	rep movsw		; move last part
     0 000001BA 5A                      	pop dx
     0 000001BB 58                      	pop ax
     0 000001BC EB43                    	jmp short .return
   409                                  
   410                                  .down:
     0 000001BE FD                      	std			; _AMD_ERRATUM_109_WORKAROUND as below
   412                                  .dnloop:
     0 000001BF 81E90010                	sub cx, 1000h		; 64 KiB left ?
     0 000001C3 761A                    	jbe .dnlast		; no -->
     0 000001C5 50                      	push ax
     0 000001C6 52                      	push dx
     0 000001C7 01C8                    	add ax, cx
     0 000001C9 01CA                    	add dx, cx
     0 000001CB 8ED8                    	mov ds, ax		; -> 64 KiB not yet moved
     0 000001CD 8EC2                    	mov es, dx
     0 000001CF 5A                      	pop dx
     0 000001D0 58                      	pop ax
     0 000001D1 BFFEFF                  	mov di, -2
     0 000001D4 89FE                    	mov si, di		; moved from last word down
     0 000001D6 51                      	push cx
     0 000001D7 B90080                  	mov cx, 10000h /2
     0 000001DA F3A5                    	rep movsw		; move 64 KiB
     0 000001DC 59                      	pop cx
     0 000001DD EBE0                    	jmp short .dnloop	; proceed for more -->
   430                                  .dnlast:
     0 000001DF 81C10010                	add cx, 1000h		; restore counter
     0 000001E3 D1E1                    	shl cx, 1
     0 000001E5 D1E1                    	shl cx, 1
     0 000001E7 D1E1                    	shl cx, 1		; *8, paragraphs to words
     0 000001E9 89CF                    	mov di, cx
     0 000001EB 4F                      	dec di
     0 000001EC D1E7                    	shl di, 1		; words to offset, -> last word
     0 000001EE 89FE                    	mov si, di
     0 000001F0 8ED8                    	mov ds, ax
     0 000001F2 8EC2                    	mov es, dx		; first segment correct
   441                                  
   442                                  
   443                                  	numdef AMD_ERRATUM_109_WORKAROUND, 1
   444                                  		; Refer to comment in init.asm init_movp.
   445                                  
   446                                  %if _AMD_ERRATUM_109_WORKAROUND
     0 000001F4 E308                    	jcxz @FF
     0 000001F6 83F914                  	cmp cx, 20
     0 000001F9 7703                    	ja @FF
   450                                  @@:
     0 000001FB A5                      	movsw
     0 000001FC E2FD                    	loop @B
   453                                  @@:
   454                                  %endif
     0 000001FE F3A5                    	rep movsw		; move first part
     0 00000200 FC                      	cld
   457                                  .return:
     0 00000201 5F                      	pop di
     0 00000202 07                      	pop es
     0 00000203 5E                      	pop si
     0 00000204 1F                      	pop ds
     0 00000205 59                      	pop cx
     0 00000206 C3                      	retn
   464                                  %endif
   465                                  
   466                                  
   467                                  msg:
   468                                  .internal_error_memory:
     0 00000207 0D0A496E7465726E61      	db 13,10,"Internal error, lacking memory for nonrelocated stack."
     0 00000210 6C206572726F722C20
     0 00000219 6C61636B696E67206D
     0 00000222 656D6F727920666F72
     0 0000022B 206E6F6E72656C6F63
     0 00000234 617465642073746163
     0 0000023D 6B2E
     0 0000023F 0D0A24                  	db 13,10,36
   471                                  %if _MZEXESUPPORT
   472                                  .internal_error_format:
     0 00000242 0D0A496E7465726E61      	db 13,10,"Internal error, MZ exe has invalid header or too large."
     0 0000024B 6C206572726F722C20
     0 00000254 4D5A20657865206861
     0 0000025D 7320696E76616C6964
     0 00000266 20686561646572206F
     0 0000026F 7220746F6F206C6172
     0 00000278 67652E
     0 0000027B 0D0A24                  	db 13,10,36
   475                                  %elif 01
   476                                  .internal_error_mz:
   477                                  	db 13,10,"Internal error, MZ exe not supported."
   478                                  	db 13,10,36
   479                                  %endif
   480                                  
     0 0000027E 26<rep 2h>              	align 16, db 38
   482                                  COMLOADER_end:
   483                                  
   484                                  %assign COMLOADERSIZE (COMLOADER_end - COMLOADER_start)
   485                                  %warning comloadersize=%[COMLOADERSIZE]
   485          ******************       warning: comloadersize=640 [-w+user]
