
; Public Domain

; test run command: ; .; .

%include "lmacros3.mac"
%include "eld.mac"
%include "eldcall.mac"
%include "elddata.mac"

	numdef MCP, 0
	numdef COMPRESSED, 0
	numdef COMPRESSLIB, 0
%assign _ELDCOMPRESSED _COMPRESSED
	numdef ALIGNPAGE, 1
	excdef !_COMPRESSED, ALIGNPAGE
	numdef DATABUFFER, 1
	numdef ELD_TEST_LIB, 0
	numdef ELD_TEST_DESCRIBEX, 0
 	numdef ELD_ZERO_OFFSETS, 0

%assign _DEBUG 1
%assign _CATCHINT0C 0
%assign _CATCHINT0D 0
%assign _CATCHINTFAULTCOND 0
%assign _LOADER 0
%assign _DEBUG_COND 1
%assign _DELAY_BEFORE_BP 0
%assign _DHIGHLIGHT 0
%assign _GETLINEHIGHLIGHT 0
%assign _IMMASM 0
%assign _INPUT_FILE_BOOT 0
%assign _INPUT_FILE_HANDLES 0
%assign _MS_0RANGE_COMPAT 0
%assign _PM 0
%assign _RH 0
%assign _SYMBOLIC 0
%assign _VXCHG 0
%include "options.mac"

%include "iniload.mac"

	numdef XLD

%ifn _COMPRESSLIB
	cpu 8086

	addsection RELOCATEDDATA, nobits vstart=_ELD_RELOC_VSTART
relocateddata:

	addsection HEADER, start=0

	istruc ELD_HEADERX
at eldhxHeader
		; ELD executable header
	istruc ELD_HEADER
at eldhSignature,	db "ELD1"
			db 0,0,0
			db 26
at eldhCodeOffset,	dd CODEOFFSET
at eldhCodeImageLength,	dw code_size
at eldhCodeAllocLength,	dw 0
at eldhDataOffset,	dd DATAOFFSET
at eldhDataImageLength,	dw data_size
at eldhDataAllocLength,	dw total_data_size - data_size
at eldhCodeEntrypoint,	dw linker - code
at eldhReserved
at eldhExtensionSize,	dw header_extension_end - $$
	iend
at eldhxDescriptionOffset,	dd description
at eldhxHelpOffset,		dd DATAOFFSET + msg.help - datastart
at eldhxLibTable,		dd DATAOFFSET + libtable - datastart
PUT_ELDHX_DATETIME_OFFSET
header_extension_end:
	iend

description:
%if _MCP
	db "MCP "
%endif
	asciz "EXT LIB: library of ELDs."


	align 16, db 0

CODEOFFSET equ $ - $$
	addsection CODE, follows=HEADER vstart=_ELD_CODE_VSTART
%define CODEFIXUP - code + 0
code:
		; ELD instance header
	istruc ELD_INSTANCE
at eldiStartCode
at eldiEndCode
at eldiStartData
at eldiEndData
at eldiIdentifier,	fill 8, 32, db "EXTLIB"
at eldiListing,		asciz _ELD_LISTING
	iend


load:
	call get_es_ext
	mov di, code
internalcoderelocation
	mov ax, word [es:di + eldiEndCode]
	sub ax, strict word endload + code
internalcoderelocation
	mov word [es:di + eldiEndCode], endload + code
internalcoderelocation
	sub word [relocateddata], ax
linkdatarelocation extseg_used
	push ss
	pop es

%assign _BOOTLDR 1
%assign _APPLICATION 1
%assign _DEVICE 1
%assign _PM 1
%define relocated(address) relocateddata
%define doscall extcallcall _doscall
%assign ELD 1
%assign _DOSORBOOTIO 1

%include "loadeld.asm"

.error_internal:
	mov si, msg.ext_error_internal
internaldatarelocation
	jmp specificerror

.io_error:
	mov si, msg.ext_error_io
internaldatarelocation
	jmp specificerror

.invalid:
	mov si, msg.ext_error_invalid
internaldatarelocation
	jmp specificerror

.oom:
	mov si, msg.ext_error_oom
internaldatarelocation
	; jmp specificerror

specificerror:
	push ss
	pop ds
	push ss
	pop es
	mov ah, 0Eh
	lodsb
	extcall setrc
	mov dx, si
	extcallcall putsz
zero_and_cmd3:
%if _ELD_ZERO_OFFSETS
	call zerooffsets
%endif
	extcallcall cmd3



dos_or_boot_io:
%if _BOOTLDR
reloc	testopt [ss:relocateddata], nodosloaded
linkdatarelocation internalflags, -3
	jnz .boot
%endif
.dos:
	cmp ax, 3FFFh
	je @F
	extcall _doscall
	retn

@@:
	extcall doscall_extseg
	retn

%if _BOOTLDR
.boot:
	cmp ah, 3Fh
	jne @F
	cmp al, 0FFh
	jne .bootread
.bootread_ext:
	push ds
	pop es
	push ss
	pop ds
.bootread:
	extcall yy_boot_read.bx
	push ss
	pop es
	retn

@@:
	cmp ax, 4200h
	jne @F
	sub dx, word [relocateddata - LOADDATA2 + ldCurrentSeek]
linkdatarelocation load_data
	sbb cx, word [relocateddata - LOADDATA2 + ldCurrentSeek + 2]
linkdatarelocation load_data

.boot_seek_current:
	extcall yy_boot_seek_current.bx
	mov ax, word [relocateddata - LOADDATA2 + ldCurrentSeek]
linkdatarelocation load_data
	mov dx, word [relocateddata - LOADDATA2 + ldCurrentSeek + 2]
linkdatarelocation load_data
	retn

@@:
	cmp ax, 4201h
	je .boot_seek_current
	extcallcall error
%endif


%if _COMPRESSED
%assign _STANDALONE 0
 %ifn _ELD_TEST_DESCRIBEX
  %define ELD_OMIT_PARTIALDEPACK
 %endif
 %include "depack.asm"
%endif


get_es_ext:
reloc	mov es, word [relocateddata]
linkdatarelocation extdssel
	extcallcall ispm
	jz @F
reloc	mov es, word [relocateddata]
linkdatarelocation extseg
@@:
	retn


	align 2
relocator:
	push si
	push di
	push ds
	push es

	 push es
	 pop ds
	mov cx, 0
.codelength equ $ - 2
	mov si, 0
.codesource equ $ - 2
	mov di, code
.codedestination equ $ - 2
internalcoderelocation
	rep movsb

	 push ss
	 pop es
	 push ss
	 pop ds
	mov cx, 0
.datalength equ $ - 2
	mov si, 0
.datasource equ $ - 2
	mov di, datastart
.datadestination equ $ - 2
internaldatarelocation
	rep movsb

	pop es
	mov word [relocateddata], 0
linkdatarelocation extseg_used, -4
.extseg_used equ $ - 2
	mov word [relocateddata], 0
linkdatarelocation extdata_used, -4
.extdata_used equ $ - 2

	mov cx, 0
.entry equ $ - 2
	pop ds
	pop di
	pop si
	jmp cx

	align 2
	endarea relocator

	eldcall_dump_callcall ELDCALL_CALLCALL_LIST
	eldcall_new_callcall

endload: equ ($ + _CURRENT_SECTION %+ FIXUP + 15) & ~15


start:
	push ss
	pop es
%if _DATABUFFER
reloc	testopt [relocateddata], nodosloaded
linkdatarelocation internalflags, -3
	jz .skipdatabuffer
	mov cl, 4
	mov ax, ss
reloc	mov bx, databuffer
internaldatarelocation
	test bl, 15
	jnz .skipdatabuffer
	shr bx, cl
	add ax, bx
reloc	mov word [relocateddata - LOADDATA2 + ldDataSegment], ax
linkdatarelocation load_data
	xor ax, ax
reloc	mov word [relocateddata - LOADDATA2 + ldDataSector + 2], ax
linkdatarelocation load_data
reloc	mov word [relocateddata - LOADDATA2 + ldDataSector], ax
linkdatarelocation load_data
reloc	setopt [relocateddata - LOADDATA2 + ldFlags], ldfDataBuffered
linkdatarelocation load_data, -3
.skipdatabuffer:
%endif
	extcallcall skipcomma
	lea bx, [si - 1]
	extcallcall iseol?
	je help_dec
	dec si
	mov dx, msg.help_keyword
internaldatarelocation
	extcallcall isstring?
	je help
%if _COMPRESSED && _ELD_TEST_LIB
	mov dx, msg.test_keyword
internaldatarelocation
	extcallcall isstring?
	je test
%endif
	lodsb
	jmp getname

%if _COMPRESSED && _ELD_TEST_LIB
test:
	call get_dxax_seek_lib_zero
	jc .io_error
	mov word [libseek], ax
internaldatarelocation
	mov word [libseek + 2], dx
internaldatarelocation

	mov cx, ELD_HEADERX_size
	sub sp, cx

	xor ax, ax
	mov word [depackskip], ax
internaldatarelocation
	mov word [depackskip + 2], ax
internaldatarelocation

	mov dx, sp
	call read_and_depack
	houdini

	mov ax, (library_end_skip - library_start_skip - 16) & 0FFFFh
	mov dx, (library_end_skip - library_start_skip - 16) >> 16

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

	mov cx, ELD_HEADERX_size
	mov dx, sp
	call read_and_depack
	houdini
	jc .io_error
	cmp cx, ax
	jne .io_error
.io_error:
	mov word [depackskip], 30h
internaldatarelocation -4
	mov word [depackskip + 2], 0
internaldatarelocation -4

	mov cx, 32
	mov dx, sp
	call read_and_depack
	houdini

	extcallcall cmd3
%endif

help_dec:
	dec si
help:
	xor cx, cx
	extcallcall skipcomma
	extcallcall iseol?
	je .dispatch_eol
	dec si
	inc cx
	mov dx, msg.describe_keyword
internaldatarelocation
	extcallcall isstring?
	je .dispatch
%if _ELD_TEST_DESCRIBEX
%if _COMPRESSED
	not byte [partialdepack]
internaldatarelocation
%endif
	mov dx, msg.describex_keyword
internaldatarelocation
	extcallcall isstring?
	je .dispatch
%endif
	inc cx
	mov dx, msg.wide_keyword
internaldatarelocation
	extcallcall isstring?
	je .dispatch
	jmp error

.dispatch:
	lodsb
	extcallcall chkeol
.dispatch_eol:
	mov dx, msg.help
internaldatarelocation
	extcallcall putsz

	dec cx
	js zero_and_cmd3
	jz describe

wide:
	mov dx, msg.list
internaldatarelocation
	extcallcall putsz

	mov si, lib
internaldatarelocation
	jmp @F
.loop:
	cmp di, relocateddata + 9 * 8
linkdatarelocation line_out
	jb @FF
	extcallcall trimputs
@@:
reloc	mov di, relocateddata
linkdatarelocation line_out
@@:
	lodsw
	lodsw			; si += 4
	mov cx, 8
	rep movsb
	mov al, 32
	stosb

	cmp si, strict word lib_end
internaldatarelocation
	jb .loop
	extcallcall trimputs
%if _ELD_ZERO_OFFSETS
	call zerooffsets
%endif
	extcallcall cmd3


describe:
	mov dx, msg.list
internaldatarelocation
	extcallcall putsz

	call get_dxax_seek_lib_zero
	jc .io_error
	mov word [libseek], ax
internaldatarelocation
	mov word [libseek + 2], dx
internaldatarelocation

	mov si, lib
internaldatarelocation
.loop:
	lea dx, [si + 4]
	mov cx, 8
	push bx
	extcallcall puts
	pop bx
	mov dx, msg.between
internaldatarelocation
	extcallcall putsz

%if _COMPRESSED
	mov ax, word [si]
	mov dx, word [si + 2]

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

	mov word [depackskip], ax
internaldatarelocation
	mov word [depackskip + 2], dx
internaldatarelocation
%else
	mov dx, word [libseek]
internaldatarelocation
	mov cx, word [libseek + 2]
internaldatarelocation

	add dx, word [si]
	adc cx, word [si + 2]

	mov ax, 4200h
	call dos_or_boot_io
	jc .io_error
	mov word [eldheader], ax
internaldatarelocation
	mov word [eldheader + 2], dx
internaldatarelocation
%endif

	mov cx, ELD_HEADERX_size
	sub sp, cx
	mov dx, sp
%if _COMPRESSED
	call read_and_depack
%else
	mov ax, 3F00h
	call dos_or_boot_io
%endif
	jc .io_error
	cmp cx, ax
	jne .io_error

	mov di, sp
	cmp word [di + eldhExtensionSize], eldhxDescriptionOffset + 4
	jb .nodesc
	mov cx, word [di + eldhxDescriptionOffset + 2]
	mov dx, word [di + eldhxDescriptionOffset]
	mov ax, cx
	or ax, dx
	jz .nodesc

	mov ax, 4200h
	add dx, word [eldheader]
internaldatarelocation
	adc cx, word [eldheader + 2]
internaldatarelocation
%if _COMPRESSED
	mov word [depackskip], dx
internaldatarelocation
	mov word [depackskip + 2], cx
internaldatarelocation
%else
	call dos_or_boot_io
	jc .io_error
%endif

	mov di, relocateddata
linkdatarelocation line_out
	mov dx, di
	xor ax, ax
	mov cx, words(128)
	rep stosw
	mov cl, 127
%if _COMPRESSED
	call read_and_depack
%else
	mov ax, 3F00h
	call dos_or_boot_io
%endif
	jc .io_error
	; cmp cx, ax
	; jne .io_error

	extcallcall putsz
	mov dx, msg.linebreak
internaldatarelocation
	jmp @F
.nodesc:
	mov dx, msg.nodesc
internaldatarelocation
@@:
	extcallcall putsz
	add sp, ELD_HEADERX_size
	add si, 4 + 8
	cmp si, strict word lib_end
internaldatarelocation
	jb .loop

.io_error equ found.io_error
%if _ELD_ZERO_OFFSETS
	call zerooffsets
%endif
	extcallcall cmd3


%if _ELD_ZERO_OFFSETS
zerooffsets:
		; for debugging with eldcomp, zero the offsets
	xor ax, ax
	mov di, ..@eldltOffset
internaldatarelocation
	stosw
	stosw			; clear eldltOffset
 %if _COMPRESSED
	stosw
	stosw			; clear libtab_compressed_length
 %endif
.loop:
	stosw
	stosw
	add di, 8
	cmp di, strict word lib_end
internaldatarelocation
	jb .loop
	retn
%endif


unquoted:
.loop:
	lodsb
.first:
	cmp al, 32
	je end
	cmp al, 9
	je end
	cmp al, ','
	je end
	extcallcall iseol?.notsemicolon
	jne .loop
	jmp end

getname:
	cmp al, '"'
	je quoted
	cmp al, "'"
	jne unquoted.first
quoted:
	inc bx
	mov ah, al
.loop:
	lodsb
	cmp al, ah
	je end_quoted
	extcallcall iseol?.notsemicolon
	jne .loop
unexpected_eol:
	mov si, msg.unexpected_eol
internaldatarelocation
	jmp specificerror

end_quoted:
	lea cx, [si - 1]
	lodsb
	jmp @F

end:
	lea cx, [si - 1]
@@:
	extcallcall skipcomm0
	dec si

	push si
	sub cx, bx
	jz notfound_invalid

	cmp cl, 4
	jb .notext
	lea si, [bx - 4]
	add si, cx
	lodsb
	cmp al, '.'
	jne .notext
	lodsb
	and al, ~20h
	cmp al, 'E'
	je @F
	cmp al, 'X'
	jne .notext
@@:
	lodsw
	and ax, ~2020h
	cmp ax, "LD"
	jne .notext
.ext:
	sub cl, 4
	jz notfound_invalid
.notext:

	cmp cl, 8
	ja notfound_invalid
	mov si, bx
	mov di, msg.namebuffer
internaldatarelocation
@@:
	lodsb
	extcallcall uppercase
	stosb
	loop @B

search_filename:
	mov si, lib + 4
internaldatarelocation
.loop:
	call comparenamebuffer
	je found
	add si, 8 + 4
	cmp si, strict word lib_end
internaldatarelocation
	jb .loop

search_instancename:
	call get_dxax_seek_lib_zero
	jc .io_error
	mov word [libseek], ax
internaldatarelocation
	mov word [libseek + 2], dx
internaldatarelocation

	mov si, lib + 4
internaldatarelocation

.loop:
%if _COMPRESSED
	mov ax, word [si - 4]
	mov dx, word [si - 4 + 2]

	mov word [depackskip], ax
internaldatarelocation
	mov word [depackskip + 2], dx
internaldatarelocation
%else
	mov cx, word [si - 4 + 2]
	mov dx, word [si - 4]		; cx:dx = offset within lib section
	add dx, word [libseek]
internaldatarelocation
	adc cx, word [libseek + 2]
internaldatarelocation
	mov ax, 4200h
	call dos_or_boot_io
	jc .io_error
%endif

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

	mov cx, ELD_HEADER_size
	sub sp, cx
	mov dx, sp
%if _COMPRESSED
	call read_and_depack
%else
	mov ax, 3F00h
	call dos_or_boot_io
%endif
	jc .io_error
	cmp cx, ax
	jne .io_error

	mov di, sp
	mov cx, word [di + eldhCodeOffset + 2]
	mov dx, word [di + eldhCodeOffset] ; cx:dx = offset within ELD
	add dx, word [eldheader]
internaldatarelocation
	adc cx, word [eldheader + 2]
internaldatarelocation
%if _COMPRESSED
	mov word [depackskip], dx
internaldatarelocation
	mov word [depackskip + 2], cx
internaldatarelocation
%else
	mov ax, 4200h
	call dos_or_boot_io
	jc .io_error
%endif

	mov dx, sp
	mov cx, eldiIdentifier + 8
%if (eldiIdentifier + 8) > ELD_HEADER_size
 %error Expected shorter instance header
%endif
%if _COMPRESSED
	call read_and_depack
%else
	mov ax, 3F00h
	call dos_or_boot_io
%endif
	jc .io_error
	cmp cx, ax
	jne .io_error

	lea cx, [di + eldiIdentifier]
	call comparenamebuffer.cx
	je .found
	add sp, ELD_HEADER_size

	add si, 8 + 4
	cmp si, strict word lib_end
internaldatarelocation
	jb .loop
	; jmp notfound
	mov si, msg.notfound
internaldatarelocation
	jmp specificerror_j

.found:
	add sp, ELD_HEADER_size

%ifn _COMPRESSED
	mov dx, word [eldheader]
internaldatarelocation
	mov cx, word [eldheader + 2]
internaldatarelocation
	mov ax, 4200h
	call dos_or_boot_io
	jc .io_error
%endif
		; get_dxax_seek_lib_* already called
	jmp found.header_variable

.io_error equ found.io_error


found:
		; get_dxax_seek_lib_* not yet called
%if 0
	xor ax, ax
	retf
%endif

%if _COMPRESSED
	call get_dxax_seek_lib_zero
	jc .io_error
	mov word [libseek], ax
internaldatarelocation
	mov word [libseek + 2], dx
internaldatarelocation

	mov dx, word [si - 4 + 2]
	mov ax, word [si - 4]		; dx:ax = offset within lib section
%else
	mov cx, word [si - 4 + 2]
	mov dx, word [si - 4]		; cx:dx = offset within lib section

	call get_dxax_seek_lib_plus_cxdx
	jc .io_error
%endif
	mov word [eldheader], ax
internaldatarelocation
	mov word [eldheader + 2], dx
internaldatarelocation
		; get_dxax_seek_lib_* already called
.header_variable:
	jmp load

.io_error equ load.io_error


notfound_invalid:
	mov si, msg.notfound.invalid
internaldatarelocation
specificerror_j:
	jmp specificerror


comparenamebuffer:
	mov cx, si
.cx:
	push si
	mov si, cx
	mov di, msg.namebuffer
internaldatarelocation
	mov cx, 8
@@:
	lodsb
	extcallcall uppercase
	scasb
	loope @B
	pop si
	retn

	dw relocateddata		; link only for checking support
linkdatarelocation ext_finish.bp_is_set

		; This must be called exactly once, if at all.
		;  It expects that the current file seek is as
		;  left over from our ELD instance having been
		;  loaded, ie it -> behind our data section.
		; This seeks once to the library image plus the
		;  displacement given by cxdx.
get_dxax_seek_lib_zero:
	xor cx, cx
	xor dx, dx
get_dxax_seek_lib_plus_cxdx:
	mov bx, relocateddata
linkdatarelocation load_data_lowest	; make yy_boot_get and yy_boot_update no-ops
	testopt [relocateddata], nodosloaded
linkdatarelocation internalflags, -3
	jnz @F
	mov bx, [relocateddata]
linkdatarelocation ext_handle
	extcall InDOS
	jz @F
	extcallcall error
@@:
	mov ax, 4201h
lib_displacement equ LIBOFFSET - (DATAOFFSET + data_size)
%if lib_displacement
	add dx, lib_displacement & 0FFFFh
	adc cx, (lib_displacement >> 16) & 0FFFFh
%endif
	rol byte [got_seek_lib], 1
internaldatarelocation
	jnc @F
	mov si, msg.error_seek_lib
internaldatarelocation
	jmp specificerror
@@:
	not byte [got_seek_lib]
internaldatarelocation
	jmp dos_or_boot_io


DATAOFFSET equ CODEOFFSET + code_size
	addsection DATA, follows=CODE vstart=_ELD_DATA_VSTART
datastart:
PUT_ELD_DATETIME

%define INCBINLIST db ""

	%imacro libeld 1-2.nolist
%strcat %%label "lib_", %1
%deftok %%token %%label
%if _XLD
 %strcat %%filename %1,".xld"
%else
 %strcat %%filename %1,".eld"
%endif
%xdefine INCBINLIST INCBINLIST, {align 16, db 0}, %%token:, incbin %%filename
	dd %%token
	fill 8, 32, db %1
	%endmacro

	%imacro dump_incbin 1-*.nolist
%rep %0
	%1
 %rotate 1
%endrep
	%endmacro

%ifn _COMPRESSED
	overridedef LZEXEDAT, 0
%endif
%ifn _LZEXEDAT
	overridedef LONGLITERAL, 0
%endif

	align 4, db 0
libtable:
 istruc ELD_LIBTABLE
at eldltFormat,		dw 2 * !!_COMPRESSED + !!_LZEXEDAT + !!_LONGLITERAL
	; 0 = uncompressed
	; 1 = legacy heatshrink format (no libtab compressed length)
	; 2 = heatshrink format (prepended with -w and -l bytes)
	; 3 = lzexedat -4 format (current revision starts with a 1 bit)
	; 4 = lzexedat -4 -l format (current revision starts with a 1 bit)
at eldltAmount,		dw (lib_end - lib) / 12
at eldltOffset
..@eldltOffset:		dd LIBOFFSET
 iend
 %if _COMPRESSED
libtab_compressed_length:
			dd (lib_compressed_end - lib_start)
 %endif
%else
		; Collect the binaries and compress them solidly.
	%imacro libeld 1-2.nolist
%strcat %%label "lib_", %1
%deftok %%token %%label
%if _XLD
 %strcat %%filename %1,".xld"
%else
 %strcat %%filename %1,".eld"
%endif
	align 16, db 0
%%token:
	incbin %%filename
	%endmacro
%endif

	numdef ELD_DEBUG_LIB, 0
lib:
%if _ELD_DEBUG_LIB
libeld "eldteste"
libeld "eldtestf"
%else
libeld "aformat"
libeld "alias"
libeld "amiscmd"
libeld "amismsg"
libeld "amisoth"
libeld "amitsrs"
libeld "amount"
libeld "bases"
libeld "bootdir"
libeld "checksum"
libeld "chstool"
libeld "co"
libeld "config"
libeld "dbitmap"
libeld "devices"
libeld "dhm"
libeld "di"
libeld "dm"
libeld "doscd"
libeld "dosdir"
libeld "dosdrive"
libeld "dospwd"
libeld "dosseek"
libeld "dosspace"
libeld "dosstrat"
libeld "dpb"
libeld "dtadisp"
libeld "dx"
libeld "enamelib"
libeld "errfix"
libeld "extname"
%if _MCP
libeld "fdbplace"
%endif
libeld "hint"
libeld "hintoth"
libeld "history"
libeld "ifext"
libeld "inject"
libeld "instnoth"
libeld "instnoun"
libeld "kcmdline"
libeld "kdisplay"
libeld "ldmem"
libeld "ldmemoth"
libeld "linfo"
libeld "list"
libeld "patchqry"
libeld "path"
libeld "printf"
libeld "quiet"
libeld "quit"
libeld "rcexec"
libeld "rdumpidx"
libeld "rdumpstr"
libeld "reclaim"
libeld "reserve"
libeld "rm"
libeld "rn"
libeld "s"
libeld "sbranch"
libeld "set"
libeld "tsc"
libeld "useparat"
libeld "variable"
libeld "withhdr"
libeld "x"
%endif
lib_end:

%ifn _COMPRESSLIB
%if _COMPRESSED
	align 2, db 0
depack_saved_sp:	dw 0FFFFh
 %if _ELD_TEST_DESCRIBEX
partialdepack:		db 0FFh
 %endif
%endif

got_seek_lib:		db 0

msg:
.ext_error_internal:	asciz 39h,"Internal error in EXT LIB command.",13,10
.ext_error_io:		asciz 3Ah,"EXT LIB command got I/O error.",13,10
.ext_error_invalid:	asciz 3Bh,"EXT LIB: No or invalid Extension for lDebug header.",13,10
.ext_error_oom:		asciz 3Ch,"Out of memory in EXT LIB command.",13,10
.error_seek_lib:	asciz 7Fh,"Internal error in EXT LIB, multiple seek to library.",13,10
.notfound:		db 37h,'EXT LIB: No ELD found by the name "'
.namebuffer:		times 8 db 32
			asciz '"!',13,10
.notfound.invalid:	asciz 38h,"EXT LIB: No ELD found, invalid name!",13,10
.between:		asciz "  "
.nodesc:		db "No description."
.linebreak:		asciz 13,10

depack_stack: equ $

.unexpected_eol:	asciz 36h,"EXT LIB: Unexpected End Of Line, expected closing quote mark!",13,10
.help_keyword:		asciz "HELP"
.describe_keyword:	asciz "DESCRIBE"
%if _ELD_TEST_DESCRIBEX
.describex_keyword:	asciz "DESCRIBEX"
%endif
%if _COMPRESSED && _ELD_TEST_LIB
.test_keyword:		asciz "TEST"
%endif
.wide_keyword:		asciz "WIDE"
.help:
%if _MCP
			db "MCP "
%endif
			db "EXT LIB command. This ELD is a library of other ELDs.",13,10
			db "Run with an ELD instance name to run another ELD.",13,10
			db "Run with HELP DESCRIBE to dump descriptions (slow)",13,10
			db " or with HELP WIDE to display only known ELD names (fast).",13,10
			asciz
.list:			db 13,10
			asciz "List of contained ELDs:",13,10

uinit_data: equ $

	align 16, db 0
init_data_end:
data_size equ $ - datastart
transient_data_size equ data_size

%if _COMPRESSED
	absolute depack_stack
	alignb 2
		resb 256
depack_stack.top:

 %if uinit_data > depack_stack.top
	absolute uinit_data
 %endif
%else
	absolute uinit_data
%endif

	alignb 2
libseek:	resd 1
eldheader:	resd 1

%if _COMPRESSED
depackskip:	resd 1
depackseek:	resd 1
depacked_buffer:resd 1
depack_left_length:	resw 1
depack_left_address:	resw 1
depacked_length:resw 1
depack_prior_sp:resw 1
	alignb 2
filebuffer:
%if _ALIGNPAGE
	resb 512
%else
	resb 256
%endif
.end:
	alignb 2
.next:		resw 1
.tail:		resw 1
handle:		resw 1

	alignb 16
resultbuffer:
.size equ 4096
		resb .size
.end:
%endif

%if _DATABUFFER
	alignb 16
databuffer:
	resb 512
%endif

	alignb 16
uinit_data_end:

%if uinit_data_end >= init_data_end
 total_data_size equ $ - datastart
%else
 total_data_size equ init_data_end - datastart
%endif
%assign _DATA_SIZE total_data_size

	usesection CODE

%include "eldlink.asm"

	align 16
code_size equ $ - code

%if _ALIGNPAGE
LIBOFFSETUNALIGNED equ DATAOFFSET + data_size
	addsection ALIGNED, follows=DATA vstart=0
aligned:
	times (((512) - ((LIBOFFSETUNALIGNED) % (512))) % (512)) db 0
	endarea aligned

LIBOFFSET equ LIBOFFSETUNALIGNED + aligned_size
	addsection LIB, follows=ALIGNED vstart=0
%else
LIBOFFSET equ DATAOFFSET + data_size
	addsection LIB, follows=DATA vstart=0
%endif
lib_start:

 %if _COMPRESSED
  %if _XLD
   %if _LZEXEDAT
	incbin "packlib.xlz"
   %else
	incbin "packlib.xhs"
   %endif
  %else
   %if _LZEXEDAT
	incbin "packlib.elz"
   %else
	incbin "packlib.ehs"
   %endif
  %endif
lib_compressed_end:

	align 16, db 0
length_to_truncate equ $ - lib_start + LIBOFFSET

	addsection LIBDEPACKED, follows=LIB vstart=0
library_start_skip:
 %endif

dump_incbin INCBINLIST
library_end_skip:

 %if _COMPRESSED
	dd length_to_truncate
 %endif
%endif
