
; Public Domain

%include "lmacros3.mac"

%include "eld.mac"
%include "eldcall.mac"
%include "elddata.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 "Install N extension for reserving 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 "NRESERVE"
at eldiListing,		asciz _ELD_LISTING
	iend

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

install:
	extcallcall skipcomma
	extcallcall getword
	lframe
	lenter
	lvar word, limit
	 push dx

	mov bx, 1
	extcall loader_get_resident_address
	jc haveerror
	mov ax, dx
	add ax, bx
	sub ax, [bp + ?limit]
	jbe notneeded
	xchg bx, ax
	add bx, resident_size_p
	extcall loader_get_resident_address
	jc haveerror
	add dx, resident_size_p
	cmp dx, word [bp + ?limit]
	jbe valid

invalid:
reloc	mov dx, msg.invalid
internaldatarelocation
	mov ax, 0E84h
	jmp haveerror

notneeded:
reloc	mov dx, msg.noneed
internaldatarelocation
	mov ax, 0E83h
haveerror:
	extcallcall setrc
	extcallcall putsz
	jmp leave

valid:
	extcall loader_prepare_resident
	jc haveerror
	lvar word, size
	 push bx

	mov es, dx
	mov di, resident.image - resident
	 push cs
	 pop ds
reloc	mov si, resident.image
internalcoderelocation
	mov cx, resident_size_w - words(resident.image - resident)
	rep movsw		; place resident

	 push ss
	 pop ds
	 push ss
	 pop es
reloc	testopt [relocateddata], 4
linkdatarelocation options7, -3
	jnz @F
reloc	mov di, relocateddata
linkdatarelocation line_out
reloc	mov si, msg.installed
internaldatarelocation
	extcall copy_single_counted_string
	mov ax, word [bp + ?size]
	xor dx, dx
	mov cx, 16
	xor bx, bx
	extcall disp_dxax_times_cx_width_bx_size.store
	extcall putsline_crlf
@@:
leave:
	lleave

@@:
	xor ax, ax
	retf

help:
	lodsb
	extcallcall chkeol
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


	align 16, nop
resident:
	times 16 db 0		; for NEXT image ident
.image:
signature:
.ven:	fill 8,32,db "ecm"		; vendor
.prod:	fill 8,32,db "NRESERVE"		; product
.deac:	asciz "Reserve memory N extension"

	align 16, nop
	endarea resident


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

msg:
.linebreak:		db 13,10
.empty:			asciz

uinit_data: equ $
.installed:		counted "NRESERVE installed, reserved "
.keyword_help:		asciz "HELP"
.help:		db "This ELD installs an N extension for reserving memory.",13,10
		db "This ELD can only be used by the lDOS pre-boot loader.",13,10
		db 13,10
		db "Run with INSTALL <segment> to install.",13,10
		asciz
.noneed:
	asciz "No need for reserve N extension, memory is already reserved!",13,10
.invalid:
	asciz "Invalid reserve N extension request!",13,10

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

	absolute uinit_data

	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
