
; Public Domain

; test run command: ; .; .

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

	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_ZERO_OFFSETS, 1

%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:		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

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
	dec si
	mov bx, si
	lodsb
	extcallcall iseol?
	lea si, [si - 1]
	je help
	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:
	xor cx, cx
	xor dx, dx
	call get_dxax_seek_lib_plus_cxdx
	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:
	mov cx, 2
	extcallcall skipcomma
	extcallcall iseol?
	je .dispatch_eol
	dec si
	dec cx
	mov dx, msg.describe_keyword
internaldatarelocation
	extcallcall isstring?
	je .dispatch
%if _COMPRESSED
	not byte [partialdepack]
internaldatarelocation
%endif
	mov dx, msg.describex_keyword
internaldatarelocation
	extcallcall isstring?
	je .dispatch
	dec 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

	cmp cl, 1
	jbe @F
	call zerooffsets
	extcallcall cmd3

@@:
	je 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
@@:
	lea si, [si + 4]
	mov cx, 8
	rep movsb
	mov al, 32
	stosb

	cmp si, strict word lib_end
internaldatarelocation
	jb .loop
	extcallcall trimputs
	call zerooffsets
	extcallcall cmd3


describe:
	mov dx, msg.list
internaldatarelocation
	extcallcall putsz

	xor cx, cx
	xor dx, dx
	call get_dxax_seek_lib_plus_cxdx
	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
	call zerooffsets
	extcallcall cmd3


zerooffsets:
%if _ELD_ZERO_OFFSETS
		; 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
%endif
	retn


getname:
	cmp al, '"'
	je quoted
	cmp al, "'"
	je quoted
unquoted:
	dec si
.loop:
	lodsb
	cmp al, 32
	je end
	cmp al, 9
	je end
	cmp al, ','
	je end
	extcallcall iseol?.notsemicolon
	jne .loop
	jmp end

quoted:
	inc bx
	mov ah, al
.loop:
	lodsb
	cmp al, ah
	je end_quoted
	extcallcall iseol?.notsemicolon
	jne .loop
unexpected_eol:
	mov ax, 0E36h
	extcallcall setrc
	mov dx, msg.unexpected_eol
internaldatarelocation
putsz_cmd3:
	extcallcall putsz
cmd3_j:
	extcallcall cmd3

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 cx, 4
	jb .notext
	lea si, [bx - 4]
	add si, cx
	cmp byte [si], '.'
	jne .notext
	mov ax, word [si + 2]
	and ax, ~2020h
	cmp ax, "LD"
	jne .notext
	mov al, byte [si + 1]
	and al, ~20h
	cmp al, 'E'
	je .ext
	cmp al, 'X'
	jne .notext
.ext:
	sub cx, 4
	jz notfound_invalid
.notext:

	cmp cx, 8
	ja notfound_invalid
	mov si, bx
	mov di, namebuffer
internaldatarelocation
	mov dx, cx
@@:
	lodsb
	extcallcall uppercase
	stosb
	loop @B
	neg dx
	add dx, 8
	xchg cx, dx
	mov al, 32
	rep stosb
	mov di, namebuffer
internaldatarelocation

search_filename:
	mov si, lib + 4
internaldatarelocation
.loop:
	push di
	push si
	mov cx, 8
@@:
	lodsb
	extcallcall uppercase
	scasb
	jne @F
	loop @B
@@:
	pop si
	pop di
	je found
	add si, 8 + 4
	cmp si, strict word lib_end
internaldatarelocation
	jb .loop

search_instancename:
	xor cx, cx
	xor dx, dx
	call get_dxax_seek_lib_plus_cxdx
	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

	push si
	lea si, [di + eldiIdentifier]
	mov di, namebuffer
internaldatarelocation

	push di
	mov cx, 8
@@:
	lodsb
	extcallcall uppercase
	scasb
	jne @F
	loop @B
@@:
	pop di
	pop si
	je .found
	add sp, ELD_HEADER_size

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

.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
	jmp found.header_variable

.io_error equ found.io_error


notfound:
	mov ax, 0E37h
	extcallcall setrc
	mov dx, msg.notfound.1
internaldatarelocation
	extcallcall putsz
	mov dx, di
	mov cx, 8
	extcallcall puts
	mov dx, msg.notfound.2
internaldatarelocation
	call zerooffsets
	jmp putsz_cmd3

notfound_invalid:
	mov ax, 0E38h
	extcallcall setrc
	mov dx, msg.notfound.invalid
internaldatarelocation
	call zerooffsets
	jmp putsz_cmd3

found:
%if 0
	xor ax, ax
	retf
%endif

%if _COMPRESSED
	xor cx, cx
	xor dx, dx
	call get_dxax_seek_lib_plus_cxdx
	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
.header_variable:

%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 dx, msg.ext_error_internal
internaldatarelocation
	mov ax, 0E39h
	jmp @F

.io_error:
	mov dx, msg.ext_error_io
internaldatarelocation
	mov ax, 0E3Ah
	jmp @F

.invalid:
	mov dx, msg.ext_error_invalid
internaldatarelocation
	mov ax, 0E3Bh
	jmp @F

.oom:
	mov dx, msg.ext_error_oom
internaldatarelocation
	mov ax, 0E3Ch

@@:
	extcallcall setrc
	push ss
	pop ds
	extcallcall putsz
	extcallcall cmd3


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
	extcallcall InDOS
	jz @F
	extcallcall error
@@:
	mov ax, relocateddata
linkdatarelocation ext_finish.bp_is_set

	mov ax, 4201h
lib_displacement equ LIBOFFSET - DATAOFFSET - data_size
	add dx, lib_displacement & 0FFFFh
	adc cx, (lib_displacement >> 16) & 0FFFFh
	; jmp dos_or_boot_io


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
 %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 16
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 16
	endarea relocator


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 "errfix"
libeld "extname"
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 "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
partialdepack:		db 0FFh
%endif

msg:
.ext_error_internal:	asciz "Internal error in EXT LIB command.",13,10
.ext_error_io:		asciz "EXT LIB command got I/O error.",13,10
.ext_error_invalid:	asciz "EXT LIB: No or invalid Extension for lDebug header.",13,10
.ext_error_oom:		asciz "Out of memory in EXT LIB command.",13,10
.notfound.1:		asciz 'EXT LIB: No ELD found by the name "'
.notfound.2:		asciz '"!',13,10
.notfound.invalid:	asciz "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 "EXT LIB: Unexpected End Of Line, expected closing quote mark!",13,10
.help_keyword:		asciz "HELP"
.describe_keyword:	asciz "DESCRIBE"
.describex_keyword:	asciz "DESCRIBEX"
%if _COMPRESSED && _ELD_TEST_LIB
.test_keyword:		asciz "TEST"
%endif
.wide_keyword:		asciz "WIDE"
.help:			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
namebuffer:	resb 8
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:
length_to_truncate equ $ - lib_start + LIBOFFSET

	align 16, db 0

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

dump_incbin INCBINLIST
library_end_skip:

 %if _COMPRESSED
	dd length_to_truncate
 %endif
%endif
