
; Public Domain

; test run command: ; .; .

%include "lmacros3.mac"

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

%assign _CATCHINT0C 0
%assign _CATCHINT0D 0
%assign _CATCHINTFAULTCOND 0
%assign _LOADER 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"


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

description:		asciz "Work with lDebug reserved memory."


	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 "RESERVE"
at eldiListing,		asciz _ELD_LISTING
	iend


run:
	push ss
	pop es

reloc	mov di, lineincopy
internaldatarelocation
	push di
	mov cx, words(256)
	rep movsw
	pop si

reloc2	mov word [separatormessage], msg.empty
internaldatarelocation -4
internaldatarelocation
	lodsb
	extcallcall iseol?
	jne @F
reloc	mov si, msg.display_noun + 1
internaldatarelocation
@@:
	dec si			; -> keyword

	xor ax, ax
	push ax			; on stack = 0

.loopouter:			; si -> next keyword
	lodsb
	extcallcall iseol?
	jne @F
.continue:
	pop si			; get next string
	test si, si		; any ?
	jnz .loopouter		; yes -->

reloc	rol byte [reset_no_ensure], 1
internaldatarelocation
	jnc .noreset
reloc	clropt [relocateddata], opt7_no_ensure
linkdatarelocation options7, -3
.noreset:
	retn			; done

@@:
	dec si			; -> keyword
	xchg si, cx
reloc	mov si, nountable
internaldatarelocation
.loop:
	lodsb
	mov ah, 0
	add ax, si
	cmp ax, si
	je .notfound
	xchg dx, ax		; -> match string
	xchg si, cx		; si -> keyword
	extcallcall isstring?
	je .got
	xchg si, cx		; si -> table
	lodsb
	lodsw			; skip
	jmp .loop		; try to match next noun -->

.got:
	extcallcall skipcomma
	dec si			; -> next keyword
	push si			; stack next keyword
	xchg si, cx		; si -> table
	lodsb
	test al, 2
	jz @F
	xchg si, di
	pop si
	 push ax
	lodsb
	extcallcall getdword
	extcallcall skipcomm0
	dec si			; -> next keyword
	 pop ax
	push si			; stack next keyword
	xchg si, di
reloc	mov word [number], dx
internaldatarelocation
reloc	mov word [number + 2], bx
internaldatarelocation
@@:
	cmp al, 1
	lodsw			; ax -> next string or function
	je .sublist
.function:
;	call .separator
	call ax			; call code
	 push ss
	 pop es
	 push ss
	 pop ds
	pop si			; restore -> next keyword
	jmp .loopouter		; continue noun loop -->

.sublist:
	xchg si, ax		; si -> sub list
	jmp .loopouter		; handle sub list --> (stack has continue offset)

.notfound:
	call .separator
	mov ax, 0E43h
	extcallcall setrc
reloc	mov dx, msg.notfound.1
internaldatarelocation
	extcallcall putsz
	xchg si, cx		; si -> keyword
	mov dx, si		; dx -> start of keyword
@@:
	lodsb
	extcallcall iseol?	; EOL ?
	je @F
	cmp al, 32		; blank ?
	je @F
	cmp al, 9
	je @F
	cmp al, ','		; comma ?
	jne @B
		; We do not want to loop on trailing commas
		;  indefinitely, so handle this in a special
		;  way here. (Trailing comma after a valid
		;  name will emit the not found message with
		;  an empty name.)
	push si
	extcallcall skipwhite
	extcallcall iseol?	; EOL after comma ?
	jne .nottrailingcomma
	dec si
	pop ax			; -> after keyword + 1
	dec ax			; -> after keyword
	mov cx, ax		; -> after keyword
	jmp @FF

.nottrailingcomma:
	pop si
@@:
	dec si			; -> after keyword
	mov cx, si		; -> after keyword
@@:
	sub cx, dx		; cx = length of keyword
	extcallcall puts
reloc	mov dx, msg.notfound.2
internaldatarelocation
	extcallcall putsz
	extcallcall skipcomma	; skip comma (except trailing comma)
	dec si			; -> next keyword
	jmp .loopouter

.separator:
reloc	mov dx, msg.linebreak
internaldatarelocation
reloc	xchg dx, word [separatormessage]
internaldatarelocation
	extcallcall putsz
	retn


display:
reloc	mov dx, word [relocateddata]
linkdatarelocation pspdbg
reloc	mov bx, word [relocateddata]
linkdatarelocation alloc_size_not_reserved

	test bx, bx
	jnz @F
reloc	mov dx, msg.notsupported
internaldatarelocation
	extcallcall putsz
	retn

@@:
reloc	mov cx, word [relocateddata]
linkdatarelocation alloc_size
	add dx, bx		; => reserved memory, if any
	sub cx, bx		; = size of reserved memory
	jz @F
	call .single
reloc	mov dx, word [relocateddata]
linkdatarelocation next_reserved_segment
	test dx, dx
	jnz .loop
reloc	mov dx, msg.nonereserved.chain
internaldatarelocation
	extcallcall putsz
	retn
@@:

reloc	mov dx, word [relocateddata]
linkdatarelocation next_reserved_segment
	test dx, dx
	jnz .loop
reloc	mov dx, msg.nonereserved.all
internaldatarelocation
	extcallcall putsz
	retn

.loop:
	extcallcall setes2dx
	mov cx, word [es:12]
	push word [es:14]
	call .single
.next:
	pop dx
	test dx, dx
	jnz .loop
	retn

		; INP:	cx = size in paragraphs
		;	if cx == 0,
		;	 dx => MCB
		;	else,
		;	 dx => block
		;	es unknown
.single:
	houdini
	 push ss
	 pop es
reloc	mov di, relocateddata
linkdatarelocation line_out

	xchg ax, dx		; => block or MCB
	inc ax			; => block + 1 or MCB + 1
	jcxz .zero
	dec ax			; => block
.zero:
	push cx

reloc	mov si, msg.display.1
internaldatarelocation
	extcallcall copy_single_counted_string

	extcallcall hexword

reloc	mov si, msg.display.2
internaldatarelocation
	extcallcall copy_single_counted_string

	pop ax
	extcallcall hexword

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

	xor dx, dx
	mov cx, 16
	mov bx, 9
	extcallcall disp_dxax_times_cx_width_bx_size.store

	extcallcall putsline_crlf
	retn


free:
reloc	mov dx, word [relocateddata]
linkdatarelocation pspdbg
reloc	mov bx, word [relocateddata]
linkdatarelocation alloc_size_not_reserved

	test bx, bx
	jnz @F
reloc	mov dx, msg.notsupported
internaldatarelocation
	extcallcall putsz
	retn

@@:
reloc	mov cx, word [relocateddata]
linkdatarelocation alloc_size
	sub cx, bx		; = size of reserved memory
	jz @F

	push bx
	mov ah, 4Ah			; re-alloc memory block
	call doscall_dx_for_es
reloc	mov word [relocateddata], bx
linkdatarelocation alloc_size
	pop bx

	add dx, bx		; => reserved memory, if any
	call .display

@@:
reloc	mov dx, word [relocateddata]
linkdatarelocation next_reserved_segment
	test dx, dx
	jnz .loop
reloc	mov dx, msg.nonetofree
internaldatarelocation
	extcallcall putsz
	retn

.loop:
reloc	mov dx, word [relocateddata]
linkdatarelocation next_reserved_segment
	test dx, dx
	jz .ret
	call setes2dx
	push word [es:14]
	mov cx, word [es:12]
	test cx, cx
	jne @F
	inc dx
@@:
	 push ss
	 pop es
	mov ah, 49h			; free memory block
	call doscall_dx_for_es
reloc	pop word [relocateddata]
linkdatarelocation next_reserved_segment

	call .display

	jmp .loop

.ret:
	retn


.display:
	xchg ax, cx
reloc	mov di, msg.freeing.amount
internaldatarelocation
	extcall hexword
	xchg ax, dx
reloc	mov di, msg.freeing.segment
internaldatarelocation
	extcall hexword
reloc	mov dx, msg.freeing
internaldatarelocation
	extcallcall putsz
	retn


alloc:
	xor di, di
		mov ax, 5802h			; Get UMB link state
		extcallcall _doscall
		xor ah, ah
		push ax				; Save UMB link state
		mov ax, 5800h			; Get allocation strategy
		extcallcall _doscall
		push ax				; Save allocation strategy

		mov ax, 5803h			; Set UMB link state:
		mov bx, 1			; enabled
		extcallcall _doscall
		mov ax, 5801h			; Set allocation strategy:
		xor bx, bx			; first fit, LMA then UMA
		extcallcall _doscall

.loop:
	xor bx, bx
	mov ah, 48h
	extcallcall _doscall
	jc .done
	mov dx, ax
reloc	cmp ax, word [relocateddata]
linkdatarelocation reserved_address
	jbe .grow
.free:
	mov ah, 49h
	call doscall_dx_for_es
	jmp .done

.grow:
	push ax
	xchg bx, ax
	neg bx
reloc	add bx, word [relocateddata]
linkdatarelocation reserved_address		; = reserved - bx
	mov ah, 4Ah
	call doscall_dx_for_es			; grow up to desired segment
						;  (if not free grow less)

	mov ax, bx
reloc	mov di, msg.allocating.amount
internaldatarelocation
	extcall hexword
	pop ax
reloc	mov di, msg.allocating.segment
internaldatarelocation
	extcall hexword
reloc	mov dx, msg.allocating
internaldatarelocation
	extcallcall putsz
	mov di, -1

	test bx, bx
	jnz .nonempty
	dec ax					; => MCB (hack into the name field)
.nonempty:
	mov dx, ax
	extcallcall setes2dx
	mov word [es:12], bx			; size (0 if in MCB)
reloc	xchg ax, word [relocateddata]		; :12 -> chain
linkdatarelocation next_reserved_segment
	mov word [es:14], ax			; => next in chain
	 push ss
	 pop es
	jmp .loop

.done:
		pop bx				; saved allocation strategy
		mov ax, 5801h
		extcallcall _doscall		; Set allocation strategy
		pop bx				; saved UMB link state
		mov ax, 5803h
		extcallcall _doscall		; Set UMB link state

	test di, di
	jnz .ret
reloc	mov dx, msg.none.allocating
internaldatarelocation
	extcallcall putsz
.ret:
	retn


get:
reloc	mov ax, word [relocateddata]
linkdatarelocation reserved_address
reloc	mov di, msg.get.segment
internaldatarelocation
	extcall hexword
reloc	mov dx, msg.get
internaldatarelocation
	extcallcall putsz
	retn


set:
reloc	mov ax, word [number]
internaldatarelocation
reloc	mov di, msg.set.segment
internaldatarelocation
	extcall hexword
reloc	mov dx, msg.set
internaldatarelocation
	extcallcall putsz
reloc	mov word [relocateddata], ax
linkdatarelocation reserved_address
	retn


getenv:
	houdini
reloc	mov dx, word [relocateddata]
linkdatarelocation pspdbe
reloc	cmp dx, word [relocateddata]
linkdatarelocation pspdbg
	je .error
	inc dx
	jz .error
	dec dx
	jz .error
	extcallcall setes2dx
	mov dx, word [es:2Ch]
	test dx, dx
	jz .none
	dec dx
	extcallcall setes2dx
	mov ax, word [es:3]

	push ss
	pop es
reloc	mov di, msg.getenv.amount
internaldatarelocation
	extcall hexword
reloc	mov dx, msg.getenv
internaldatarelocation
	extcallcall putsz
reloc	mov word [envsize], ax
internaldatarelocation
	retn

.error:
	push ss
	pop es
reloc	mov dx, msg.getenv.error
internaldatarelocation
	extcallcall putsz
	retn

.none:
	push ss
	pop es
reloc	mov dx, msg.getenv.none
internaldatarelocation
	extcallcall putsz
	retn


setenv:
reloc	mov ax, word [number]
internaldatarelocation
reloc	mov di, msg.setenv.amount
internaldatarelocation
	extcall hexword
reloc	mov dx, msg.setenv
internaldatarelocation
	extcallcall putsz
reloc	mov word [envsize], ax
internaldatarelocation
	retn


allocenv:
reloc	mov bx, word [envsize]
internaldatarelocation
	mov ah, 48h
	extcallcall _doscall
	jc .error

reloc	mov di, msg.allocenv.segment
internaldatarelocation
	extcallcall hexword
reloc	mov dx, msg.allocenv
internaldatarelocation
	extcallcall putsz

reloc	mov word [allocated_env], ax
internaldatarelocation

reloc	push word [relocateddata]
linkdatarelocation ext_inject_handler
reloc	pop word [injectprior.deallocenv]
internaldatarelocation

reloc2	mov word [relocateddata], .inject
linkdatarelocation ext_inject_handler, -4
internalcoderelocation

	call get_es_ext
reloc	inc word [residentcount]
internaldatarelocation
reloc	setopt [es:code + eldiFlags], eldifResident
internalcoderelocation -3		; mark block as resident
	push ss
	pop es
	retn


.error:
reloc	mov dx, msg.allocenv.error
internaldatarelocation
	jmp putsz


.inject:
	call do_free_env

reloc	mov cx, word [injectprior.deallocenv]
internaldatarelocation
	call get_es_ext
reloc	dec word [residentcount]
internaldatarelocation
	jnz @F
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


freeenv:
do_free_env:
	xor dx, dx
reloc	xchg dx, word [allocated_env]
internaldatarelocation
	test dx, dx
	jz @F
	mov ah, 49h
	call doscall_dx_for_es
@@:
	retn


qa:
	xor ax, ax
reloc	mov byte [reset_no_ensure], al
internaldatarelocation
reloc	testopt [relocateddata], opt7_no_ensure
linkdatarelocation options7, -3
	jnz @F
reloc	not byte [reset_no_ensure]
internaldatarelocation
@@:
reloc	setopt [relocateddata], opt7_no_ensure
linkdatarelocation options7, -3

reloc	push word [relocateddata]
linkdatarelocation ext_inject_handler
reloc	push word [relocateddata]
linkdatarelocation savesp
reloc	push word [relocateddata]
linkdatarelocation throwsp
reloc	mov word [eld_sp], sp
internaldatarelocation
reloc	mov word [relocateddata], sp
linkdatarelocation savesp
reloc	mov word [relocateddata], sp
linkdatarelocation throwsp

reloc2	mov word [relocateddata], .inject
linkdatarelocation ext_inject_handler, -4
internalcoderelocation

	call get_es_ext
reloc	inc word [residentcount]
internaldatarelocation
reloc	setopt [es:code + eldiFlags], eldifResident
internalcoderelocation -3		; mark block as resident
	push ss
	pop es
	extcallcall cmd3

.inject:
reloc	mov si, qabuffer
internaldatarelocation
reloc	mov di, relocateddata + 1
linkdatarelocation line_in

	extcallcall yy_reset_buf
	push di
	mov cx, words(256)
	rep movsw
	pop si
	inc si
	extcallcall skipwhite

reloc2	mov word [relocateddata], .finish
linkdatarelocation ext_inject_handler, -4
internalcoderelocation
	extcall cmd3_injected

.finish:
reloc	mov sp, word [eld_sp]
internaldatarelocation
reloc	pop word [relocateddata]
linkdatarelocation throwsp
reloc	pop word [relocateddata]
linkdatarelocation savesp
reloc	pop word [relocateddata]
linkdatarelocation ext_inject_handler
	call get_es_ext
reloc	dec word [residentcount]
internaldatarelocation
	jnz @F
reloc	clropt [es:code + eldiFlags], eldifResident
internalcoderelocation -3		; mark block as no longer resident
@@:
	 push ss
	 pop es
	retn


l:
reloc	push word [relocateddata]
linkdatarelocation ext_inject_handler
reloc	push word [relocateddata]
linkdatarelocation savesp
reloc	push word [relocateddata]
linkdatarelocation throwsp
reloc	mov word [eld_sp], sp
internaldatarelocation
reloc	mov word [relocateddata], sp
linkdatarelocation savesp
reloc	mov word [relocateddata], sp
linkdatarelocation throwsp

reloc2	mov word [relocateddata], .inject
linkdatarelocation ext_inject_handler, -4
internalcoderelocation

	call get_es_ext
reloc	inc word [residentcount]
internaldatarelocation
reloc	setopt [es:code + eldiFlags], eldifResident
internalcoderelocation -3		; mark block as resident
	push ss
	pop es
	extcallcall cmd3

.inject:
reloc	mov si, lbuffer
internaldatarelocation
reloc	mov di, relocateddata + 1
linkdatarelocation line_in

	extcallcall yy_reset_buf
	push di
	mov cx, words(256)
	rep movsw
	pop si
	inc si
	extcallcall skipwhite

reloc2	mov word [relocateddata], .finish
linkdatarelocation ext_inject_handler, -4
internalcoderelocation
	extcall cmd3_injected

.finish:
reloc	mov sp, word [eld_sp]
internaldatarelocation
reloc	pop word [relocateddata]
linkdatarelocation throwsp
reloc	pop word [relocateddata]
linkdatarelocation savesp
reloc	pop word [relocateddata]
linkdatarelocation ext_inject_handler
	call get_es_ext
reloc	dec word [residentcount]
internaldatarelocation
	jnz @F
reloc	clropt [es:code + eldiFlags], eldifResident
internalcoderelocation -3		; mark block as no longer resident
@@:
	 push ss
	 pop es
	retn


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


doscall_dx_for_es:
	extcallcall ispm
	jnz .rm

subcpu 286
	push dx
	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:
	mov es, dx
	int 21h
	mov dx, es
@@:
	push ss
	pop es
	retn


start:
	mov bx, es
	 push ss
	 pop es
	call skipcomma
	dec si
reloc	mov dx, msg.keyword_help
internaldatarelocation
	call isstring?
	je help
	call run
@@:
	call uninstall_oneshot
	xor ax, ax
	retf

help:
	lodsb
	extcall chkeol
reloc	mov dx, msg.help
internaldatarelocation
	call 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:
PUT_ELD_DATETIME

	align 2, db 0
nountable:
	db msg.display_noun - $ - 1
	db 0
reloc	dw display
internalcoderelocation
	db msg.free_noun - $ - 1
	db 0
reloc	dw free
internalcoderelocation
	db msg.alloc_noun - $ - 1
	db 0
reloc	dw alloc
internalcoderelocation
	db msg.get_noun - $ - 1
	db 0
reloc	dw get
internalcoderelocation
	db msg.set_noun - $ - 1
	db 2
reloc	dw set
internalcoderelocation
	db msg.getenv_noun - $ - 1
	db 0
reloc	dw getenv
internalcoderelocation
	db msg.setenv_noun - $ - 1
	db 2
reloc	dw setenv
internalcoderelocation
	db msg.allocenv_noun - $ - 1
	db 0
reloc	dw allocenv
internalcoderelocation
	db msg.freeenv_noun - $ - 1
	db 0
reloc	dw freeenv
internalcoderelocation
	db msg.qa_noun - $ - 1
	db 0
reloc	dw qa
internalcoderelocation
	db msg.l_noun - $ - 1
	db 0
reloc	dw l
internalcoderelocation
	db msg.reload_noun - $ - 1
	db 1
reloc	dw msg.reload_replace
internaldatarelocation
	dw 0

envsize:
	dw 0
allocated_env:
	dw 0
injectprior:
.deallocenv:
	dw 0
residentcount:
	dw 0
eld_sp:
	dw 0

reset_no_ensure:
	db 0

qabuffer:
	counted "QA"
	db 13

lbuffer:
	counted "L"
	db 13

msg:
.display_noun:		asciz "DISPLAY"
.free_noun:		asciz "FREE"
.alloc_noun:		asciz "ALLOC"
.get_noun:		asciz "GET"
.set_noun:		asciz "SET"
.getenv_noun:		asciz "GETENV"
.setenv_noun:		asciz "SETENV"
.allocenv_noun:		asciz "ALLOCENV"
.freeenv_noun:		asciz "FREEENV"
.qa_noun:		asciz "QA"
.l_noun:		asciz "L"
.reload_noun:		asciz "RELOAD"
.reload_replace:	asciz "l getenv qa free allocenv alloc freeenv l"
.notfound.1:		asciz 'Noun "'
.notfound.2:		asciz '" not found!',13,10

.nonetofree:		asciz "No chained reserved memory to free!",13,10
.freeing:		db "Freeing "
.freeing.amount:	db "----h paragraphs at segment "
.freeing.segment:	asciz "----h",13,10
.none.allocating:	asciz "No reserved memory to allocate!",13,10
.allocating:		db "Allocating "
.allocating.amount:	db "----h paragraphs at segment "
.allocating.segment:	asciz "----h",13,10
.get:			db "Reserved memory limit is at segment "
.get.segment:		asciz "----h.",13,10
.set:			db "Reserved memory limit set to segment "
.set.segment:		asciz "----h.",13,10
.getenv:
.setenv:		db "Environment size is "
.getenv.amount:
.setenv.amount:		asciz "----h paragraphs.",13,10
.getenv.error:		asciz "Cannot get environment size, no DOS process attached!",13,10
.getenv.none:		asciz "Unable to get environment size!",13,10
.allocenv.error:	asciz "Unable to allocate environment block!",13,10
.allocenv:		db "Allocated environment block at segment "
.allocenv.segment:	asciz "----h.",13,10
.linebreak:		db 13,10
.empty:			asciz
.notsupported:		asciz "Reserved memory not supported.",13,10
.nonereserved.chain:	asciz "No chained reserved memory.",13,10
.nonereserved.all:	asciz "No reserved memory.",13,10
.display.1:		counted "Segment: "
.display.2:		counted " size="
.display.3:		counted "h paragraphs, "

uinit_data: equ $
.keyword_help:		asciz "HELP"
.help:		db "This ELD can only be used transiently.",13,10
		db 13,10
		db "Any number of keywords can be passed to this ELD to choose action:",13,10
		db 9,"(none)",9,9,"Alias to DISPLAY",13,10
		db 9,"DISPLAY",9,9,"Display reserved memory",13,10
		db 9,"FREE",9,9,"Free reserved memory",13,10
		db 9,"ALLOC",9,9,"Allocate reserved memory",13,10
		db 9,"GET",9,9,"Get reserved memory limit",13,10
		db 9,"SET number",9,"Set reserved memory limit",13,10
		db 9,"GETENV",9,9,"Get (remember) current environment size",13,10
		db 9,"SETENV number",9,"Set (remember) specified environment size",13,10
		db 9,"ALLOCENV",9,"Allocate block of environment size (freed at end)",13,10
		db 9,"FREEENV",9,9,"Free block of environment size",13,10
		db 9,"QA",9,9,"Run QA command then continue this ELD's run",13,10
		db 9,"L",9,9,"Run plain L command then continue this ELD's run",13,10
		db 9,"RELOAD",9,9,"Run: l getenv qa free allocenv alloc freeenv l",13,10
		asciz

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

	absolute uinit_data
	alignb 2
separatormessage:
	resw 1
number:
	resd 1

lineincopy:
	resb 2 + 255

	alignb 16
uinit_data_end:
resident_data_end:
resident_data_size equ resident_data_end - datastart

%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
