
; Public Domain

; test run command: ; .; .

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

	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 "Operate on config or scripts path."

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


run:
	push ss
	pop es
	dec si
reloc	mov dx, msg.show
internaldatarelocation
	extcallcall isstring?
	je show
reloc	mov dx, msg.set
internaldatarelocation
	extcallcall isstring?
	je set
	jmp error


show:
	call which
	lodsb
	extcallcall chkeol
	mov dx, bx
	mov cx, word [di]
	sub cx, dx
	extcallcall puts
reloc	mov dx, msg.linebreak
internaldatarelocation
	extcallcall putsz
	extcallcall cmd3


set:
	call which
	extcallcall skipcomma
	dec si
	mov dx, si		; dx -> source
@@:
	lodsb
	extcallcall iseol?.notsemicolon
	jne @B			; si -> after EOL
@@:
	dec si			; -> at EOL
	cmp dx, si
	jae @F
	cmp byte [si - 1], 32
	je @B
	cmp byte [si - 1], 9
	je @B			; truncate trailing blanks -->
@@:
	push di
	mov di, bx		; -> our buffer
	mov cx, si
	sub cx, dx		; = length
	cmp cx, 128
	jb @F
	mov ax, 0E1Fh
	extcallcall setrc
reloc	mov dx, msg.toolong
internaldatarelocation
	extcallcall putsz
	extcallcall cmd3

@@:
	mov si, dx		; -> source
	rep movsb		; copy to buffer
	mov al, 0
	stosb			; terminate
	mov dx, bx		; -> buffer
reloc	testopt [relocateddata], nodosloaded
linkdatarelocation internalflags, -3
	jz .dos
	mov si, dx
	mov ah, 0
.loop:
	lodsb
	cmp al, '\'
	je .sep
	cmp al, '/'
	jne .notsep
.sep:
	mov ah, '/'
	jmp .loop

.notsep:
	cmp al, 0
	je @F
	mov ah, 0
	jmp .loop

@@:
	test ah, ah
	jnz @F
	mov word [si - 1], '/'
	inc si
@@:
	dec si
	mov di, si
	jmp @F

.dos:
	call do_truename
@@:
	pop bx
	mov word [bx], di
	extcallcall cmd3


do_truename:
.:
	mov si, dx		; ds:si -> source
	mov di, dx		; es:di -> destination (same)
	mov ah, 60h
	extcallcall _doscall	; es = ds = ss
	jnc .done
	cmp byte [si], 0	; empty ? (kernel rejects this)
	mov word [si], "."	; make a dot + NUL (current directory)
	je .			; if expected failure then repeat -->

.done:
	mov al, 0
	mov cx, 128
	repne scasb		; scan for NUL
	dec di			; -> at the NUL

@@:
	cmp di, si
	jbe @F
	cmp byte [di - 1], '/'
	je @FF
	cmp byte [di - 1], '\'
	je @FF
@@:
	mov byte [di], '\'
	inc di
@@:
	retn


which:
	extcallcall skipcomma
	dec si
reloc	mov bx, relocateddata
linkdatarelocation configpath
reloc	mov di, relocateddata
linkdatarelocation configpath.dir_end
reloc	mov dx, msg.config
internaldatarelocation
	extcallcall isstring?
	je .have
reloc	mov bx, relocateddata
linkdatarelocation scriptspath
reloc	mov di, relocateddata
linkdatarelocation scriptspath.dir_end
reloc	mov dx, msg.scripts
internaldatarelocation
	extcallcall isstring?
	je .have
.error:
	extcallcall error

.have:
	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:

msg:
.show:			asciz "SHOW"
.set:			asciz "SET"
.config:		asciz "CONFIG"
.scripts:		asciz "SCRIPTS"
.string_help:		asciz "HELP"
.toolong:		asciz "Error, too long pathname given!",13,10
.help:		db "Run with a SHOW keyword to show current paths.",13,10
		db "Run with a SET keyword to modify paths.",13,10
		db 13,10
		db "After the keyword, the noun must follow:",13,10
		db 9,"CONFIG",9,"Operate on ::config:: path",13,10
		db 9,"SCRIPTS",9,"Operate on ::scripts:: path",13,10
		db 13,10
		db "For SET the pathname to set follows after the noun."
.linebreak:	asciz 13,10

uinit_data: equ $

	align 16, db 0
data_size equ $ - datastart

	absolute uinit_data

	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
