
%if 0

lDebug load Extensions for lDebug

Copyright (C) 2008-2024 E. C. Masloch

Usage of the works is permitted provided that this
instrument is retained with the works, so that any entity
that uses the works is notified of this instrument.

DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

%endif

%if ELD
%assign _ELDTRAILER 0
		numdef DOSORBOOTIO, 0
		numdef ELDCOMPRESSED, 0
%else
%assign _DOSORBOOTIO 0
%assign _ELDCOMPRESSED 0
	push bp
%endif

%if _ELDTRAILER
	xor ax, ax
	mov word [eldheader], ax
internaldatarelocation
	mov word [eldheader + 2], ax
internaldatarelocation

	xchg cx, ax
	mov ax, 4202h
	xor dx, dx
%if _BOOTLDR
 %if _APPLICATION || _DEVICE
	testopt [relocated(internalflags)], nodosloaded
linkdatarelocation internalflags, -3
	jz @F
 %endif
	extcallcall yy_boot_seek_start.bx
	mov cx, word [load_data - LOADDATA2 + ldFileSize + 2]
internaldatarelocation
	mov dx, word [load_data - LOADDATA2 + ldFileSize]
internaldatarelocation
	extcallcall yy_boot_seek_current.bx
	mov dx, word [load_data - LOADDATA2 + ldCurrentSeek + 2]
internaldatarelocation
	mov ax, word [load_data - LOADDATA2 + ldCurrentSeek]
internaldatarelocation
 %if _APPLICATION || _DEVICE
	jmp @FF
 %endif
%endif

@@:
%if _APPLICATION || _DEVICE
	doscall
%endif
@@:
	jc .io_error

	test dx, dx
	jnz @F
	cmp ax, ELD_HEADER_size + ELD_TRAILER_HEADER_size
	jb .no_trailer
@@:

	mov ax, 4201h
	mov cx, -1
	mov dx, - ELD_TRAILER_HEADER_size
%if _BOOTLDR
 %if _APPLICATION || _DEVICE
	testopt [relocated(internalflags)], nodosloaded
linkdatarelocation internalflags, -3
	jz @F
 %endif
	extcallcall yy_boot_seek_current.bx
	mov dx, word [load_data - LOADDATA2 + ldCurrentSeek + 2]
internaldatarelocation
	mov ax, word [load_data - LOADDATA2 + ldCurrentSeek]
internaldatarelocation
 %if _APPLICATION || _DEVICE
	jmp @FF
 %endif
%endif

@@:
%if _APPLICATION || _DEVICE
	doscall
%endif
@@:
	jc .io_error

	push dx
	push ax

	mov cx, fromwords(ELD_TRAILER_HEADER_size_w)
	sub sp, cx
	mov dx, sp

	mov ah, 3Fh
%if _BOOTLDR
 %if _APPLICATION || _DEVICE
	testopt [relocated(internalflags)], nodosloaded
linkdatarelocation internalflags, -3
	jz @F
 %endif
	extcallcall yy_boot_read.bx
 %if _APPLICATION || _DEVICE
	jmp @FF
 %endif
%endif

@@:
%if _APPLICATION || _DEVICE
	doscall
%endif
@@:
	jc .io_error
	mov di, sp
	mov si, sp

	cmp ax, cx
	jne .no_trailer_pop

	xor dx, dx
	shr cx, 1
@@:
	lodsw
	add dx, ax
	loop @B
	jnz .no_trailer_pop

	pop ax
	cmp ax, "EL"
	jne .no_trailer_pop
	pop ax
	cmp ax, "D1"
	jne .no_trailer_pop
	pop ax
	cmp ax, "TA"
	jne .no_trailer_pop
	pop ax
	cmp ax, "IL"
	jne .no_trailer_pop

	pop si
	pop cx			; cx:si = displacement to subtract
	pop ax			; reserved
	pop ax			; checksum

	pop ax
	pop dx			; dx:ax = offset of trailer header
	add ax, si
	adc dx, cx		; dx:ax = offset of header
	jnc .io_error

	mov word [eldheader], ax
internaldatarelocation
	mov word [eldheader + 2], dx
internaldatarelocation

.no_trailer_pop:
	lea sp, [di + fromwords(ELD_TRAILER_HEADER_size_w) + 4]

.no_trailer:
	mov ax, 4200h
	mov dx, word [eldheader]
internaldatarelocation
	mov cx, word [eldheader + 2]
internaldatarelocation

%if _BOOTLDR
 %if _APPLICATION || _DEVICE
	testopt [relocated(internalflags)], nodosloaded
linkdatarelocation internalflags, -3
	jz @F
 %endif
	extcallcall yy_boot_seek_start.bx
	extcallcall yy_boot_seek_current.bx
 %if _APPLICATION || _DEVICE
	jmp @FF
 %endif
%endif

@@:
%if _APPLICATION || _DEVICE
	doscall
%endif
@@:
	jc .io_error
%endif

	mov cx, fromwords(ELD_HEADER_size_w)
	sub sp, cx
	mov dx, sp		; es:dx and ds:dx
%if _ELDCOMPRESSED
	push word [eldheader + 2]
internaldatarelocation
	push word [eldheader]
internaldatarelocation
	pop word [depackskip]
internaldatarelocation
	pop word [depackskip + 2]
internaldatarelocation

	call read_and_depack
%elif _DOSORBOOTIO
	mov ax, 3F00h
	call dos_or_boot_io
%else
	mov ah, 3Fh
%if _BOOTLDR
 %if _APPLICATION || _DEVICE
	testopt [relocated(internalflags)], nodosloaded
linkdatarelocation internalflags, -3
	jz @F
 %endif
	extcallcall yy_boot_read.bx
 %if _APPLICATION || _DEVICE
	jmp @FF
 %endif
%endif

@@:
%if _APPLICATION || _DEVICE
	doscall
%endif
@@:
%endif
	jc .io_error
	cmp ax, cx
	jne .invalid

	mov di, sp

	pop ax
	cmp ax, "EL"
	jne .invalid
	pop ax
	cmp ax, "D1"
	jne .invalid
	pop ax
	pop ax
	cmp ah, 26
	jne .invalid

	mov ax, word [relocated(extseg_size)]
linkdatarelocation extseg_size
	sub ax, word [relocated(extseg_used)]
linkdatarelocation extseg_used
	jc .error_internal
%if ELD
	sub ax, relocator_size
	jc .error_internal
%endif

	mov cx, word [di + eldhCodeImageLength]
%if ELD
	cmp ax, cx
	jb .oom
%endif
	add cx, word [di + eldhCodeAllocLength]
	jc .invalid_CY
	add cx, 15
	jc .invalid_CY
	and cl, ~ 15

%if ELD
	add ax, word [cs:code + eldiEndCode]
internalcoderelocation
	sub ax, word [cs:code + eldiStartCode]
internalcoderelocation
%endif
	cmp ax, cx
	jb .oom

	mov dx, word [relocated(extdata_size)]
linkdatarelocation extdata_size
	sub dx, word [relocated(extdata_used)]
linkdatarelocation extdata_used
	jc .error_internal

	mov si, word [di + eldhDataImageLength]
%if ELD
	cmp dx, si
	jb .oom
%endif
	add si, word [di + eldhDataAllocLength]
	jc .invalid_CY
	add si, 15
.invalid_CY:
	jc .invalid
	and si, ~ 15

%if ELD
	add dx, word [cs:code + eldiEndData]
internalcoderelocation
	sub dx, word [cs:code + eldiStartData]
internalcoderelocation
%endif
	cmp dx, si
	jb .oom

	push si
	push cx

	mov ax, 4200h
	mov cx, word [di + eldhCodeOffset + 2]
	mov dx, word [di + eldhCodeOffset]
%if ELD || _ELDTRAILER
	add dx, word [eldheader]
internaldatarelocation
	adc cx, word [eldheader + 2]
internaldatarelocation
%else
		; ELD header is at seek 0
%endif
%if _ELDCOMPRESSED
	mov word [depackskip], dx
internaldatarelocation
	mov word [depackskip + 2], cx
internaldatarelocation
%elif _DOSORBOOTIO
	call dos_or_boot_io
%else
%if _BOOTLDR
 %if _APPLICATION || _DEVICE
	testopt [relocated(internalflags)], nodosloaded
linkdatarelocation internalflags, -3
	jz @F
 %endif
	extcallcall yy_boot_seek_start.bx
	extcallcall yy_boot_seek_current.bx
 %if _APPLICATION || _DEVICE
	jmp @FF
 %endif
%endif

@@:
%if _APPLICATION || _DEVICE
	doscall
%endif
@@:
%endif
	jc .io_error

	mov dx, word [relocated(extseg_used)]
linkdatarelocation extseg_used
%if _PM
	extcallcall ispm
	jnz @F
	mov ds, word [relocated(extdssel)]
linkdatarelocation extdssel
	jmp @FF

@@:
%endif
	mov ds, word [relocated(extseg)]
linkdatarelocation extseg
@@:
	mov cx, word [ss:di + eldhCodeImageLength]
%if _ELDCOMPRESSED
	push ds
	pop es
	push ss
	pop ds
	call read_and_depack
	push ss
	pop es
%elif _DOSORBOOTIO
	mov ax, 3FFFh
	call dos_or_boot_io
%else
	mov ah, 3Fh
%if _BOOTLDR
 %if _APPLICATION || _DEVICE
	testopt [ss:relocated(internalflags)], nodosloaded
linkdatarelocation internalflags, -3
	jz @F
 %endif
	push ds
	pop es
	push ss
	pop ds
	extcallcall yy_boot_read.bx
	push ss
	pop es
 %if _APPLICATION || _DEVICE
	jmp @FF
 %endif
%endif

@@:
%if _APPLICATION || _DEVICE
%if _PM
	extcallcall doscall_extseg
%else
	doscall
%endif
%endif
@@:
%endif
	 push ss
	 pop ds
	jc .io_error
	cmp cx, ax
	jne .io_error

	mov ax, 4200h
	mov cx, word [di + eldhDataOffset + 2]
	mov dx, word [di + eldhDataOffset]
%if ELD || _ELDTRAILER
	add dx, word [eldheader]
internaldatarelocation
	adc cx, word [eldheader + 2]
internaldatarelocation
%else
		; ELD header is at seek 0
%endif

%if _ELDCOMPRESSED
	mov word [depackskip], dx
internaldatarelocation
	mov word [depackskip + 2], cx
internaldatarelocation
%elif _DOSORBOOTIO
	call dos_or_boot_io
%else
%if _BOOTLDR
 %if _APPLICATION || _DEVICE
	testopt [relocated(internalflags)], nodosloaded
linkdatarelocation internalflags, -3
	jz @F
 %endif
	extcallcall yy_boot_seek_start.bx
	extcallcall yy_boot_seek_current.bx
 %if _APPLICATION || _DEVICE
	jmp @FF
 %endif
%endif

@@:
%if _APPLICATION || _DEVICE
	doscall
%endif
@@:
%endif
	jc .io_error

%if ELD
	mov dx, word [relocateddata]
linkdatarelocation extdata
%else
	mov dx, ext_data_area
%endif
	add dx, word [relocated(extdata_used)]
linkdatarelocation extdata_used
	mov cx, word [di + eldhDataImageLength]
%if _ELDCOMPRESSED
	call read_and_depack
%elif _DOSORBOOTIO
	mov ax, 3F00h
	call dos_or_boot_io
%else
	mov ah, 3Fh
%if _BOOTLDR
 %if _APPLICATION || _DEVICE
	testopt [relocated(internalflags)], nodosloaded
linkdatarelocation internalflags, -3
	jz @F
 %endif
	extcallcall yy_boot_read.bx
 %if _APPLICATION || _DEVICE
	jmp @FF
 %endif
%endif

@@:
%if _APPLICATION || _DEVICE
	doscall
%endif
@@:
%endif
	jc .io_error
	cmp cx, ax
	jne .io_error

%if _PM
	call get_es_ext
%else
	mov es, word [extseg]
%endif

%if ELD
	mov bx, word [relocateddata]
linkdatarelocation extseg_used		; es:bx -> where we loaded code

	mov ax, [di + eldhCodeEntrypoint]
	add ax, strict word code	; -> entry destination
internalcoderelocation
	mov word [es:relocator.entry], ax
internalcoderelocation

	mov ax, word [di + eldhCodeImageLength]
	mov word [es:relocator.codelength], ax
internalcoderelocation

	mov ax, word [di + eldhDataImageLength]
	mov word [es:relocator.datalength], ax
internalcoderelocation

	pop ax

	mov word [es:bx + eldiStartCode], code
internalcoderelocation			; fix its start

	mov di, ax
	add di, word [relocateddata]
linkdatarelocation extseg_used		; di -> relocator destination
	push ax
	add ax, relocator_size
	add word [es:code + eldiEndCode], ax
internalcoderelocation			; grow our allocation
	add word [relocateddata], ax
linkdatarelocation extseg_used		; ditto
	pop ax

	mov word [es:relocator.codesource], bx
internalcoderelocation			; -> start
	add ax, strict word code
internalcoderelocation
	mov word [es:bx + eldiEndCode], ax
					; -> past destination
	mov word [es:relocator.extseg_used], ax
internalcoderelocation			; new extseg_used

	pop ax

	mov dx, word [relocateddata]
linkdatarelocation extdata_used
	add dx, word [relocateddata]
linkdatarelocation extdata

	mov word [es:relocator.datasource], dx
internalcoderelocation

	houdini
	mov dx, datastart
internaldatarelocation
	mov word [es:bx + eldiStartData], dx
	add ax, dx
	mov word [es:bx + eldiEndData], ax

	sub ax, word [relocateddata]
linkdatarelocation extdata
	mov word [es:relocator.extdata_used], ax
internalcoderelocation			; new extdata_used

	mov dx, code
internalcoderelocation			; es:dx -> ELD code instance (dest)
	mov bx, datastart
internaldatarelocation

	mov si, relocator
internalcoderelocation
	mov cx, words(relocator_size)
	 push es
	 pop ds
	push di
	rep movsw
	pop cx				; -> relocator entry
	push ss
	pop ds
%else
	pop ax				; allocated code size
	mov dx, word [extseg_used]
	mov bp, dx
	mov word [es:bp+eldiStartCode], dx
					; -> loaded code
	add ax, word [extseg_used]
	mov word [extseg_used], ax	; -> behind
	mov word [es:bp+eldiEndCode], ax; -> behind

	pop ax				; allocated data size
	mov bx, word [extdata_used]
	add bx, ext_data_area		; -> loaded data
	mov word [es:bp+eldiStartData], bx
	add word [extdata_used], ax	; = amount new used
	add ax, bx			; -> behind
	mov word [es:bp+eldiEndData], ax

	mov cx, [di + eldhCodeEntrypoint]
	add cx, dx
%endif
	add sp, ELD_HEADER_size - 8

%if ELD
	pop si
	mov ax, word [relocateddata]
linkdatarelocation linksel
	extcallcall ispm
	jz @F
	mov ax, word [relocateddata]
linkdatarelocation linkseg
@@:

	mov di, relocateddata
linkdatarelocation linkinfoaddress
	mov di, [di]
	mov ds, ax

	jmp cx
		; INP:	es:dx -> loaded initial ELD image
		;	 ELD instance structure filled
		;	es => ELD code area
		;	ds:di -> link info
		;	ss:bx -> loaded initial data
		;	ss:si -> command line tail
		;	cs:ip -> entrypoint
		;	ss:sp -> far return address for current mode
		; STT:	UP, EI
%else
ext_finish.bp_is_set equ $
	pop bp

	mov si, word [ext_cmdline]

%if _MESSAGESEGMENT
 %if _PM
	call get_messagesegsel
 %else
 	mov ds, word [ss:messageseg]
 %endif
%endif
	mov di, linkinfo

	push cs
	call .transfer
		; INP:	es:dx -> loaded initial ELD image
		;	 ELD instance structure filled
		;	es => ELD code area
		;	ds:di -> link info
		;	ss:bx -> loaded initial data
		;	ss:si -> command line tail
		;	cs:ip -> entrypoint
		;	ss:sp -> far return address for current mode
		; STT:	UP, EI
%endif
