
; Public Domain

; test run command: list.eld; .; .

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

%assign _CATCHINT0C 0
%assign _CATCHINT0D 0
%assign _CATCHINTFAULTCOND 0
%assign _DEBUG 0
%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 BOOTLDR, 1
	numdef BOOTLDR_WILD, 1

	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
header_extension_end:
	iend

description:		asciz "Display ELD description lines."

	align 16, db 0

	eldstrict on

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 "LIST"
	iend


run:
	push ss
	pop es
%if _BOOTLDR
reloc	testopt [relocateddata], nodosloaded
linkdatarelocation internalflags, -3
	jz run_dos
.boot:
	extcallcall yy_boot_parse_name2
	call parse_verbose

 %if _BOOTLDR_WILD
	push bx
	mov di, bx
	call find_dir
	pop bx
	mov dx, di
	db __TEST_IMM8			; (skip inc)
@@:
	inc di
	cmp byte [di], 0
	je boot_no_wild
	cmp byte [di], '?'
	je boot_wild
	cmp byte [di], '*'
	jne @B

boot_wild:
reloc	mov word [wild_pattern], dx
internaldatarelocation

	extcall yy_boot_init_dir2
reloc	mov byte [relocateddata], 0
linkdatarelocation load_check_dir_attr, -3
reloc	mov si, word [relocateddata]
linkdatarelocation load_yyname_input
	cmp byte [si], '/'
	jne @F
	inc si
@@:
	cmp byte [si], 0
	jne @F
	extcall ..@yy_filename_empty
@@:
	 push ss
	 pop es
	call boot_parse_name
	cmp al, '/'
	jne @F
reloc	mov byte [relocateddata], ATTR_DIRECTORY
linkdatarelocation load_check_dir_attr, -3
reloc	mov word [relocateddata], si
linkdatarelocation load_yyname_next
@@:

	mov di, -1
	mov si, di
	mov [bp + lsvFATSector], di
	mov [bp + lsvFATSector + 2], si

	xor ax, ax
	xor dx, dx

scan_dir_yyname_loop:
	mov word [bp + ldDirCluster], ax
	mov word [bp + ldDirCluster + 2], dx

	push ss
	pop es
reloc	mov bx, relocateddata
linkdatarelocation load_yy_direntry

reloc2	mov word [relocateddata], relocateddata
linkdatarelocation handle_scan_dir_not_found, -4
;linkdatarelocation near_transfer_ext_entry
linkdatarelocation dmycmd
	extcall scan_dir_aux
	jc end_of_directory

reloc	cmp byte [relocateddata], ATTR_DIRECTORY
linkdatarelocation load_check_dir_attr, -3
	jne got_single_yyentry

	push si
	push di
reloc	mov byte [relocateddata], 0
linkdatarelocation load_check_dir_attr, -3
reloc	mov si, word [relocateddata]
linkdatarelocation load_yyname_next
	cmp byte [si], 0
	jne @F
	extcall ..@yy_filename_empty
@@:
	push es
	 push ss
	 pop es
	call boot_parse_name
	pop es
	cmp al, '/'
	jne @F
reloc	mov byte [relocateddata], ATTR_DIRECTORY
linkdatarelocation load_check_dir_attr, -3
reloc	mov word [relocateddata], si
linkdatarelocation load_yyname_next
@@:
	pop di
	pop si

	xor dx, dx
	mov ax, [es:bx + deClusterLow]
				; = first cluster (not FAT32)
	cmp byte [bp + ldFATType], 32
	jne @F
	mov dx, [es:bx + deClusterHigh]
				; dx:ax = first cluster (FAT32)
@@:

	jmp scan_dir_yyname_loop

boot_parse_name:
reloc	cmp word [wild_pattern], si
internaldatarelocation
	je @F
	extcallcall boot_parse_fn	; get next pathname

reloc2	mov word [relocateddata], relocateddata
linkdatarelocation handle_scan_dir_entry, -4
linkdatarelocation scan_dir_entry

	retn

@@:
	extcallcall boot_parse_fn	; get next pathname

reloc2	mov word [relocateddata], match_wildcard
linkdatarelocation near_transfer_ext_address, -4
internalcoderelocation
reloc2	mov word [relocateddata], relocateddata
linkdatarelocation handle_scan_dir_entry, -4
linkdatarelocation near_transfer_ext_entry

	push ax
reloc	mov di, relocateddata
linkdatarelocation load_kernel_name
	mov cx, 8
	call .handle_asterisk		; handle in basename
	mov cl, 3
	call .handle_asterisk		; handle in extension
	pop ax
	retn

.handle_asterisk:
	mov al, '*'
	repne scasb			; scan for asterisk
	jne @F				; not found -->
	mov al, '?'			; fill with question marks
	dec di				; -> at the asterisk
	inc cx				; = how many bytes remain
	rep stosb			; fill this field
@@:
	retn


		; INP:	es:di -> DIRENTRY
		;	dx:ax - 1 = sector
		;	cx, si in use
		; OUT:	CY if end of directory
		;	NC if to continue,
		;	 ZR if match
		;	 NZ if mismatch
		; CHG:	bx
match_wildcard:
	cmp byte [es:di], 0
	stc
	je .ret
	mov bl, byte [es:di + deAttrib]
	test bl, ATTR_VOLLABEL
	jnz .ret_NC		; skip volume labels (and LFNs) --> (NZ)
	and bl, ATTR_DIRECTORY	; isolate directory bit
	; cmp bl, byte [load_check_dir_attr]	; is it what we're searching?
	; jne .ret_NC				; no -->
	jnz .ret_NC		; must not be directory -->
	push si
	push di
	push cx
reloc	mov si, relocateddata	; ds:si-> name to match
linkdatarelocation load_kernel_name
	mov cx, 11		; length of padded 8.3 FAT filename
@@:
	repe cmpsb		; check entry
	je @F			; match -->
	cmp byte [si - 1], '?'	; wildcard ?
	je @B			; yes --> (ZR)
				; no (NZ)
@@:
	pop cx
	pop di
	pop si
	jne .ret_NC

	push si
	push es
	push di
	push dx
	push ax
	push cx

	mov cx, DIRENTRY_size
	push ds
	 push es
	 pop ds
	mov si, di		; ds:si -> entry in directory buffer
	push ss
	pop es
reloc	mov di, relocateddata	; es:di -> destination for entry
linkdatarelocation load_yy_direntry
	push di
	rep movsb
	pop si
	pop ds

reloc	mov di, pathnamebuffer - 1
internaldatarelocation		; di -> buffer
	mov al, 0
	stosb
	push di
	mov cl, 8
	cmp byte [si], 05h
	jne @F
	mov al, 0E5h
	stosb
	dec cx
	inc si
@@:
	rep movsb
	mov cl, 9
	db __TEST_IMM8
@@:
	dec di
	cmp byte [di - 1], 32
	loope @B
	mov al, '.'
	stosb
	mov cl, 3
	rep movsb
	mov cl, 4
	db __TEST_IMM8
@@:
	dec di
	cmp byte [di - 1], 32
	loope @B
	cmp byte [di - 1], '.'
	jne @F
	dec di
@@:
	mov al, 0
	stosb

	extcallcall got_yyentry
reloc	clropt [relocateddata], dif3_auxbuff_guarded_1
linkdatarelocation internalflags3, -3
	 push ss
	 pop es
	pop dx
reloc	mov ax, relocateddata
linkdatarelocation load_data_lowest	; make yy_boot_get and yy_boot_update no-ops
	call commonhandle
reloc	setopt [relocateddata], dif3_auxbuff_guarded_1
linkdatarelocation internalflags3, -3
	pop cx
	pop ax
	pop dx
	pop di
	pop es
	pop si			; restore registers

	sub ax, 1
	sbb dx, 0
reloc	mov bx, [relocateddata]
linkdatarelocation load_adr_dirbuf_segment
	extcall read_sector	; restore sector

reloc	or byte [found], -1
internaldatarelocation -3	; NZ
.ret_NC:
	clc
.ret:
	extcall near_transfer_ext_return, required ; must NOT be extcallcall


end_of_directory:
reloc	rol byte [found], 1
internaldatarelocation
	jc @F
reloc	mov dx, msg.notfound
internaldatarelocation
	extcallcall putsz
@@:
	extcallcall cmd3

got_single_yyentry:
	extcallcall got_yyentry
	jmp @F

boot_no_wild:
 %endif

	extcallcall yy_boot_open_file2
@@:
reloc	clropt [relocateddata], dif3_auxbuff_guarded_1
linkdatarelocation internalflags3, -3
reloc	mov di, word [relocateddata]
linkdatarelocation load_yyname_input
	call find_dir
	mov dx, di
reloc	mov ax, relocateddata
linkdatarelocation load_data_lowest	; make yy_boot_get and yy_boot_update no-ops
	call commonhandle
	extcallcall cmd3
%endif

run_dos:
	extcallcall InDOS
	extcallcall yy_dos_parse_name
	call parse_verbose

	push bx

	mov ah, 2Fh			; get DTA
	extcallcall ispm
	jnz .rm

subcpu 286
	push word 0
	push word 21h
	extcall intcall_ext_return_es, PM required	; must NOT be extcallcall
	pop dx				; discard interrupt number
	pop dx				; get es
subcpureset
	jmp @F
.rm:
	int 21h
	mov dx, es
@@:

reloc	mov word [originaldta], bx
internaldatarelocation
reloc	mov word [originaldta + 2], dx
internaldatarelocation

reloc	mov ax, word [relocateddata]
linkdatarelocation ext_inject_handler
reloc	mov word [originalinject], ax
internaldatarelocation
reloc2	mov word [relocateddata], inject
linkdatarelocation ext_inject_handler, -4
internalcoderelocation
	call get_es_ext
reloc	setopt [es:code + eldiFlags], eldifResident
internalcoderelocation -3	; mark block as resident
	 push ss
	 pop es

	houdini
reloc	mov dx, dta
internaldatarelocation
	mov ah, 1Ah		; set DTA
	extcallcall _doscall

	pop dx

reloc	mov word [findnext_function_number], 714Fh
internaldatarelocation -4
	mov ax, 714Eh
	mov cx, 6		; find all files, no directories
	mov si, 1
reloc	mov di, finddata
internaldatarelocation
reloc	rol byte [prefersfn], 1
internaldatarelocation
	jc .sfn_try
	stc
	extcallcall _doscall
	jnc .lfn_found
	cmp ax, 1
	je .sfn_try
	cmp ax, 7100h
	je .sfn_try
	jmp .notfound

.lfn_found:
reloc	mov word [findhandle], ax
internaldatarelocation
reloc	mov byte [findhandle_set], 0FFh
internaldatarelocation -3
	jmp .next

.sfn_try:
reloc	mov word [findnext_function_number], 4F00h
internaldatarelocation -4
	mov ax, 4E00h
	mov cx, 6		; find all files, no directories
	extcallcall _doscall
	jc .notfound

.next:
	push dx
	mov di, dx
	call find_dir
	mov si, bx		; si -> path
	mov cx, di
	sub cx, si		; cx = length of path
reloc	mov di, pathnamebuffer
internaldatarelocation		; di -> buffer
	mov bx, di		; bx -> buffer
	rep movsb
	mov dx, di		; dx -> where we store filename
reloc	mov si, dta.name
internaldatarelocation
	mov cx, 13

reloc	cmp byte [findnext_function_number + 1], 71h
internaldatarelocation -3
	jne .sfn_copy

reloc	mov si, finddata.fullname
internaldatarelocation
	push di
	mov cx, -1
	mov al, 0
	mov di, si
	repne scasb		; cx = -2, copy 1 byte
	not cx
	pop di

.sfn_copy:
	rep movsb

	push dx
	extcallcall yy_open_file
	pop dx
reloc	mov word [relocateddata], ax
linkdatarelocation ext_handle
@@:
	call commonhandle
	extcallcall close_ext
	pop dx
reloc	mov ax, word [findnext_function_number]
internaldatarelocation
reloc	mov bx, word [findhandle]
internaldatarelocation
	mov si, 1
reloc	mov di, finddata
internaldatarelocation
	stc
	extcallcall _doscall
	jnc .next

	extcallcall cmd3


.notfound:
reloc	mov dx, msg.notfound
internaldatarelocation
	extcallcall putsz
	extcallcall cmd3


parse_verbose.loop:
	lodsb
parse_verbose:
	extcallcall skipcomm0
	extcallcall iseol?
	jne @F
	retn

@@:
	dec si
reloc	mov dx, msg.verbose
internaldatarelocation
	extcallcall isstring?
	jne @F
reloc	mov byte [verbose], 0FFh
internaldatarelocation -3
	jmp .loop

@@:
reloc	mov dx, msg.string_help
internaldatarelocation
	extcallcall isstring?
	jne @F
reloc	mov byte [do_help], 0FFh
internaldatarelocation -3
	jmp .loop

@@:
reloc	mov dx, msg.string_sfn
internaldatarelocation
	extcallcall isstring?
	jne @F
reloc	mov byte [prefersfn], 0FFh
internaldatarelocation -3
	jmp .loop

@@:
	jmp error


find_dir:
	mov bx, di		; bx -> start of path
	mov cx, -1
	mov al, 0
	repne scasb
	dec di
@@:
	cmp di, bx
	jbe .di
	dec di
	cmp byte [di], '/'
	je .di_plus_one
	cmp byte [di], '\'
	je .di_plus_one
	cmp byte [di], ':'
	jne @B
.di_plus_one:
	inc di
.di:				; di -> end of path
	retn


commonhandle:
	lframe
	lvar word, more_help
	lenter
	lvar word, handle
	 push ax
	xchg bx, ax		; bx = handle
	extcallcall putsz
	mov di, dx

reloc	mov dx, msg.colon
internaldatarelocation
	extcallcall putsz

	mov al, 0
	mov cx, -1
	repne scasb		; cx = -2 means 0 bytes, -3 means 1 bytes
%if 0
	not cx			; cx = 1 means 0 bytes
	cmp cx, 8 + 1 + 3 + 1
	jae @FF
	neg cx
	add cx, 8 + 1 + 3 + 1
%else
		; I give up, it's magic
	add cx, (8 + 1 + 3 + 1) + 1
	jnc @FF
	jz @FF
%endif
@@:
	mov al, 32
	extcallcall putc
	loop @B
@@:

	mov ah, 3Fh
	mov cx, fromwords(ELD_HEADER_size_w)
	lvar fromwords(ELD_HEADER_size_w), header
	sub sp, cx
	mov dx, sp
	call dos_or_boot_io
	jc .io_error
	cmp ax, cx
	jne .invalid
	pop ax
	cmp ax, "EL"
	jne .invalid
	pop dx
	cmp dx, "D1"
	jne .invalid
	houdini
	push dx
	push ax
	cmp word [bp + ?header + eldhExtensionSize], eldhxDescriptionOffset + 4
	jb .nodesc
	sub sp, 4
%if eldhxDescriptionOffset - ELD_HEADER_size
	mov dx, eldhxDescriptionOffset - ELD_HEADER_size
	xor cx, cx
	mov ax, 4201h
	call dos_or_boot_io
	jc .io_error
%endif
	mov dx, sp
	mov cx, 4
	mov ah, 3Fh
	call dos_or_boot_io
	jc .io_error
	cmp ax, cx
	jne .invalid
	pop dx
	pop cx
	mov ax, dx
	or ax, cx
	jz .nodesc
	mov ax, 4200h
	call dos_or_boot_io
	jc .io_error

reloc	mov di, relocateddata
linkdatarelocation line_out
	mov cx, words(128)
	xor ax, ax
	mov dx, di
	rep stosw
	mov ah, 3Fh
	mov cx, 127
	call dos_or_boot_io
	jc .io_error
	extcallcall putsz
reloc	mov dx, msg.linebreak
internaldatarelocation
.putsz_desc_done:
	extcallcall putsz

reloc	rol byte [verbose], 1
internaldatarelocation
	jnc .help
reloc	mov di, relocateddata
linkdatarelocation line_out
reloc	mov si, msg.verbose.1
internaldatarelocation
	extcallcall copy_single_counted_string

	lea si, [bp + ?header]
	movsw
	movsw

	sub sp, 8
	mov ax, 4200h
	mov cx, word [bp + ?header + eldhCodeOffset + 2]
	mov dx, word [bp + ?header + eldhCodeOffset]
		; ELD header is at seek 0
	add dx, eldiIdentifier
	adc cx, 0
	jc .invalid_instance
	call dos_or_boot_io
	jc .io_error
	mov dx, sp
	mov ah, 3Fh
	mov cx, 8
	call dos_or_boot_io
	jc .io_error
	cmp ax, cx
	jne .invalid_instance

reloc	mov si, msg.verbose.2
internaldatarelocation
	push cx
	extcallcall copy_single_counted_string
	pop cx

	mov si, sp
	rep movsb
	db __TEST_IMM8		; (skip dec)
@@:
	dec di
	cmp byte [di - 1], 32
	je @B

	add sp, 8

	mov al, '"'
	stosb

.after_invalid_instance:
	push bx
	extcallcall putsline_crlf
	pop bx
reloc	mov di, relocateddata
linkdatarelocation line_out

	mov ax, 2020h
	stosw

	mov ax, word [bp + ?header + eldhCodeImageLength]
	extcallcall decword

reloc	mov si, msg.verbose.3
internaldatarelocation
	extcallcall copy_single_counted_string

	add ax, word [bp + ?header + eldhCodeAllocLength]
	add ax, 15
	and al, ~15
	extcallcall decword

reloc	mov si, msg.verbose.4
internaldatarelocation
	extcallcall copy_single_counted_string

	mov ax, word [bp + ?header + eldhDataImageLength]
	extcallcall decword

reloc	mov si, msg.verbose.5
internaldatarelocation
	extcallcall copy_single_counted_string

	add ax, word [bp + ?header + eldhDataAllocLength]
	add ax, 15
	and al, ~15
	extcallcall decword

reloc	mov si, msg.verbose.6
internaldatarelocation
	extcallcall copy_single_counted_string

	push bx
	extcallcall putsline_crlf
	pop bx

.help:
reloc	rol byte [do_help], 1
internaldatarelocation
	jnc .ret

	cmp word [bp + ?header + eldhExtensionSize], eldhxHelpOffset + 4
	jb .nohelp
	sub sp, 4
	mov dx, eldhxHelpOffset
	xor cx, cx
	mov ax, 4200h
	call dos_or_boot_io
	jc .io_error
	mov dx, sp
	mov cx, 4
	mov ah, 3Fh
	call dos_or_boot_io
	jc .io_error
	cmp ax, cx
	jne .invalid
	pop dx
	pop cx
	mov ax, dx
	or ax, cx
	jz .nohelp
	mov ax, 4200h
	call dos_or_boot_io
	jc .io_error

reloc	mov di, relocateddata
linkdatarelocation line_out
	mov byte [bp + ?more_help], 0FFh

.loop:
	mov ax, di
reloc	sub ax, strict word relocateddata
linkdatarelocation line_out	; ax = how much already buffered

	push ax
	mov dx, di		; dx -> buffer tail
	mov ah, 3Fh		; read
reloc	mov cx, 256 + relocateddata
linkdatarelocation line_out
	sub cx, dx		; cx = how much space in buffer
	call dos_or_boot_io
	jc .io_error
%if 0
	mov si, dx
	add si, ax		; -> behind read data
	mov byte [si], 0	; may write byte [line_out + 256]
%endif
	pop cx
	add cx, ax		; = how much data we have now
	jz .ret			; if done -->

reloc	mov di, relocateddata
linkdatarelocation line_out

	push di
	push cx			; cx = 8 if 8 bytes
	mov al, 0
	repne scasb		; if cx was = 8 and second byte is NUL, cx = 6
	xchg ax, cx		; ax = 6
	pop cx
	pop di
	jne @F
	not byte [bp + ?more_help]
	sub cx, ax		; cx = 8 - 6 = 2
	dec cx			; cx = 1 (one data byte)
@@:

	mov al, 10
	add di, cx		; di -> behind data
	push cx
	dec di			; NZ, di -> last data byte
	std
	repne scasb		; scan for last LF
	cld
	pop cx
	je .partial		; found an LF -->
.full:
reloc	mov di, relocateddata - 2
linkdatarelocation line_out	; minus 2 to counteract inc inc
	add di, cx		; -> behind last data byte (minus 2)
.partial:
	inc di			; -> at LF
	inc di			; -> behind LF
	push cx
	push bx
	extcallcall putsline	; display line_out .. di-1
	pop bx
	pop cx
	mov si, di		; -> behind data displayed
reloc	mov di, relocateddata
linkdatarelocation line_out
		; cx = cx - (si - di)
	add cx, di
	sub cx, si		; cx = how much data remains
	rep movsb		; move data to start of line_out
				; di -> where to write
	rol byte [bp + ?more_help], 1
	jnc .ret
	jmp .loop

.nodesc:
reloc	mov dx, msg.nodesc
internaldatarelocation
	jmp .putsz_desc_done

.nohelp:
reloc	mov dx, msg.nohelp
internaldatarelocation
	jmp .putsz_ret

.io_error:
reloc	mov dx, msg.io_error
internaldatarelocation
	jmp .error

.invalid_instance:
reloc	mov si, msg.invalid_instance
internaldatarelocation
	extcallcall copy_single_counted_string

	add sp, 8
	jmp .after_invalid_instance

.invalid:
reloc	mov dx, msg.invalid
internaldatarelocation
.error:
.putsz_ret:
	extcallcall putsz
.ret:
	lleave , forcerestoresp
	retn


inject:
reloc	mov dx, word [originaldta]	; dx -> original DTA
internaldatarelocation
	mov ah, 1Ah			; set DTA (restoring)
	extcallcall ispm
	jnz .rm

subcpu 286
reloc	push word [originaldta + 2]
internaldatarelocation			; ds => original DTA (86M segment)
	push word 21h
	extcall intcall_ext_return_es, PM required	; must NOT be extcallcall
	pop dx				; discard interrupt number
	pop dx				; discard es
subcpureset
	jmp @F
.rm:
reloc	mov ds, word [originaldta + 2]	; ds => original DTA
internaldatarelocation
	int 21h
	 push ss
	 pop ds
@@:

reloc	mov bx, word [findhandle]	; bx = find handle, if any
internaldatarelocation
reloc	rol byte [findhandle_set], 1	; find handle set ?
internaldatarelocation
	jnc @F				; no -->
reloc	not byte [findhandle_set]
internaldatarelocation
	mov ax, 71A1h
	extcallcall _doscall		; LFN find close
@@:

reloc	mov cx, word [originalinject]
internaldatarelocation
	call get_es_ext
reloc	clropt [es:code + eldiFlags], eldifResident
internalcoderelocation -3		; mark block as no longer resident
	 push ss
	 pop es
	jcxz @F
	jmp cx

@@:
	extcall cmd3_not_inject


dos_or_boot_io:
%if _BOOTLDR
reloc	testopt [relocateddata], nodosloaded
linkdatarelocation internalflags, -3
	jnz .boot
%endif
.dos:
	extcall _doscall
	retn

%if _BOOTLDR
.boot:
	cmp ah, 3Fh
	jne @F
	extcall yy_boot_read.bx
	retn

@@:
	cmp ax, 4200h
	jne @F
	extcall yy_boot_seek_start.bx
.boot_seek_current:
	extcall yy_boot_seek_current.bx
	retn

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


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


start:
	mov bx, es
	 push ss
	 pop es
	extcallcall skipcomma
	extcallcall iseol?
	je .help
	call run
@@:
	call uninstall_oneshot
	xor ax, ax
	retf

.help:
reloc	mov dx, msg.help
internaldatarelocation
	extcallcall putsz
	jmp @B


uninstall_oneshot:
reloc	testopt [ss:relocateddata], 1
linkdatarelocation options7, -3
	jnz @F

reloc	mov ax, word [cs:code + eldiEndCode]
internalcoderelocation
reloc	sub ax, word [cs:code + eldiStartCode]
internalcoderelocation
reloc	sub word [relocateddata], ax
linkdatarelocation extseg_used

reloc	mov ax, word [cs:code + eldiEndData]
internalcoderelocation
reloc	sub ax, word [cs:code + eldiStartData]
internalcoderelocation
reloc	sub word [relocateddata], ax
linkdatarelocation extdata_used
@@:
	retn


DATAOFFSET equ CODEOFFSET + code_size
	addsection DATA, follows=CODE vstart=_ELD_DATA_VSTART
%define DATAFIXUP - datastart + 0
datastart:

findhandle_set:		db 0
found:			db 0
verbose:		db 0
do_help:		db 0
prefersfn:		db 0

msg:
.verbose:		asciz "VERBOSE"
.string_help:		asciz "HELP"
.string_sfn:		asciz "SFN"
.colon:			asciz ": "
.notfound:		asciz "File not found.",13,10
.nodesc:		asciz "No description.",13,10
.nohelp:		asciz "No help.",13,10
.io_error:		asciz "LIST ELD got I/O error.",13,10
.invalid_instance:	counted '". Invalid instance header.'
.invalid:		db "No or invalid Extension for lDebug header."
.linebreak:		asciz 13,10
.verbose.1:	counted "  Format: ",'"'
.verbose.2:	counted '", ELD name: "'
.verbose.3:	counted " code, "
.verbose.4:	counted " alloc, "
.verbose.5:	counted " data, "
.verbose.6:	counted " alloc"
.help:		db "Run with a pathname as parameter.",13,10
		db "Last component may include wildcards.",13,10
		db 13,10
		db "After the pathname, keywords may follow:",13,10
		db 9,"VERBOSE",9,"Display ELD format, name, sizes",13,10
		db 9,"HELP",9,"Display ELD help.",13,10
		asciz

uinit_data: equ $

	align 16, db 0
data_size equ $ - datastart

	absolute uinit_data

	alignb 2
wild_pattern:		; overlaps next variable
originaldta:	resd 1
originalinject:	resw 1
findnext_function_number:
		resw 1
findhandle:	resw 1
dta:		resb 1Eh
.name:		resb 13

	alignb 2
pathnamebuffer:	resb 512

finddata:	resb 2Ch
.fullname:	resb 260
.shortname:	resb 14

	alignb 16
uinit_data_end:

total_data_size equ $ - datastart
%assign _DATA_SIZE total_data_size

	usesection CODE

%include "eldlink.asm"

	align 16
code_size equ $ - code
