%if 0

Extensions for lDebug call macros

Copyright (C) 2008-2024 E. C. Masloch

Usage of the works is permitted provided that this
instrument is retained with the works, so that any entity
that uses the works is notified of this instrument.

DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

%endif

%ifndef ELDCALL_MAC
%define ELDCALL_MAC 1

%include "lmacros3.mac"
%include "nasmhash.mac"
%include "elddata.mac"

%assign ELDLINKER 0

[section relocatedzero nobits vstart=0]
relocatedzero:
__SECT__

	numdef HOUDINI, 1
	numdef HOUDINI_CONDITIONAL, 1

%imacro houdini 0.nolist
%if _HOUDINI
 %if _HOUDINI_CONDITIONAL
reloc	testopt [ss:relocateddata], 100h
linkdatarelocation options7, -3
	jz %%skip
 %endif
reloc	testopt [ss:relocateddata], 100h
linkdatarelocation internalflags6, -3
	jz %%skip
	int3
%%skip:
%endif
%endmacro

%define ELDCALL_CODE_RELOCATIONS ""
%define ELDCALL_LINKER_CODE_RELOCATIONS ""
%define ELDCALL_CODE_RELOCATIONS_OPTIONAL ""
%define ELDCALL_LINKER_CODE_RELOCATIONS_OPTIONAL ""
%define ELDCALL_CODE_NAMES db ""
%define ELDCALL_CODE_DETECTION none, none
%assign ELDCALL_OPTIONAL_STATUS 0		; not any seen yet
%assign ELDCALL_PMREQUIRED_STATUS 0		; not any seen yet

	%imacro extcall 1-2.nolist required
%ifidni _CURRENT_SECTION_TYPE, DATA
 %error "ELD call cannot be used in ELD data block"
%endif
%assign %%entry $ + _CURRENT_SECTION %+ FIXUP
%ifidni %2, required
 %assign %%optional 0
%elifidni %2, optional
 %assign %%optional 100h
 %if ELDCALL_OPTIONAL_STATUS == 0
  %assign ELDCALL_OPTIONAL_STATUS 1
 %elif ELDCALL_OPTIONAL_STATUS == 1
 %else
  %error Optional code link not allowed here
 %endif
%elifidni %2, PM required
 %assign %%optional 300h
 %assign ELDCALL_PMREQUIRED_STATUS 1
 %if ELDCALL_OPTIONAL_STATUS == 0
  %assign ELDCALL_OPTIONAL_STATUS 1
 %elif ELDCALL_OPTIONAL_STATUS == 1
 %else
  %error Optional code link not allowed here
 %endif
%else
 %fatal Unknown optional keyword
%endif
%if 0
[warning -reloc-rel-word]
	call near relocatedzero
[warning +reloc-rel-word]
%else
	db 0E8h
reloc	dw relocatedzero
	eldstrictcheck
%endif
	jmp strict short %%skipparameter
	dw 0
%%skipparameter:
%if ELDLINKER
 %xdefine ELDCALL_LINKER_CODE_RELOCATIONS ELDCALL_LINKER_CODE_RELOCATIONS, %%entry, %%name
 %xdefine ELDCALL_LINKER_CODE_RELOCATIONS_OPTIONAL ELDCALL_LINKER_CODE_RELOCATIONS_OPTIONAL, 1 + %%optional, %%entry, %%name
%else
 %xdefine ELDCALL_CODE_RELOCATIONS ELDCALL_CODE_RELOCATIONS, %%entry, %%name
 %xdefine ELDCALL_CODE_RELOCATIONS_OPTIONAL ELDCALL_CODE_RELOCATIONS_OPTIONAL, 1 + %%optional, %%entry, %%name
%endif
%defstr %%string %1
%strlen %%length %%string
%if %%length > 64
 %error Too long link name: %1
%endif
%define ELDCALL_CODE_CHECK %1
	linkcode_detect ELDCALL_CODE_DETECTION
%if ELDCALL_CODE_NEW
 %xdefine ELDCALL_CODE_DETECTION ELDCALL_CODE_DETECTION, %1, %%name
	hashdef HASH, %%string
%xdefine ELDCALL_CODE_NAMES \
	ELDCALL_CODE_NAMES, %%name:, dw _HASH, {counted %%string}
%else
 %%name equ ELDCALL_CODE_DUPLICATE
%endif
	%endmacro

	%imacro linkcode_detect 2-*.nolist
%assign ELDCALL_CODE_NEW 1
%rep (%0 - 2) / 2
 %rotate 2
 %ifidni %1, ELDCALL_CODE_CHECK
  %assign ELDCALL_CODE_NEW 0
  %xdefine ELDCALL_CODE_DUPLICATE %2
  %exitrep
 %endif
%endrep
	%endmacro


%define ELDCALL_CALLCALL_LIST none

	%imacro extcallcall 1.nolist
	call %1
%xdefine ELDCALL_CALLCALL_LIST ELDCALL_CALLCALL_LIST, %1
	%endmacro

%assign ELDCALLCALL_DUMPED 0

	%imacro eldcall_dump_callcall 1-*.nolist
%define ELDCALL_CALLCALL_PROCESSED none
 %rep %0 - 1
  %rotate 1
  %define ELDCALL_CHECK %1
	eldcall_callcall_detect ELDCALL_CALLCALL_PROCESSED
  %if ELDCALL_NEW
   %xdefine ELDCALL_CALLCALL_PROCESSED ELDCALL_CALLCALL_PROCESSED, %1
	align 8, nop
%1:
	extcall %1
	retn
  %endif
 %endrep
%unimacro extcallcall 1.nolist
%assign ELDCALLCALL_DUMPED 1
%define ELDCALL_CALLCALL_LIST none
	%endmacro

	%imacro eldcall_callcall_detect 1-*.nolist
%assign ELDCALL_NEW 1
%rep %0 - 1
 %rotate 1
 %ifidni %1, ELDCALL_CHECK
  %assign ELDCALL_NEW 0
  %exitrep
 %endif
%endrep
	%endmacro

	%imacro eldcall_dump_names 1-*.nolist
%rep %0
	%1
 %rotate 1
%endrep
	%endmacro

; eldcall_dump_callcall ELDCALL_CALLCALL_LIST
; if using optional code links:
;  dw ELDCALL_LINKER_CODE_RELOCATIONS_OPTIONAL, 0
;  dw ELDCALL_CODE_RELOCATIONS_OPTIONAL, 0
; if not using optional code links:
;  dw ELDCALL_LINKER_CODE_RELOCATIONS, 0, 0
;  dw ELDCALL_CODE_RELOCATIONS, 0, 0
; eldcall_dump_names ELDCALL_CODE_NAMES

%endif
