From adbc31edeae71b53ee41f990dc291fc9a863435e Mon Sep 17 00:00:00 2001
From: "C. Masloch" <pushbx@ulukai.org>
Date: Wed, 29 Mar 2023 20:33:53 +0200
Subject: [PATCH] update lmacros from hg 99b01fa65007

From https://hg.pushbx.org/ecm/lmacros/file/99b01fa65007
---
 test/lmacros/lmacros1.mac       |  5 ++
 test/lmacros/lmacros2.mac       | 45 +++++++++++++++++
 test/lmacros/lmacros3.mac       |  2 +
 test/lmacros/tests/testalig.asm | 88 +++++++++++++++++++++++++++++++++
 4 files changed, 140 insertions(+)
 create mode 100644 test/lmacros/tests/testalig.asm

diff --git a/test/lmacros/lmacros1.mac b/test/lmacros/lmacros1.mac
index 39d307c..fa3fa1e 100644
--- a/test/lmacros/lmacros1.mac
+++ b/test/lmacros/lmacros1.mac
@@ -131,6 +131,11 @@ Intended for 86 Mode programs.
 %xdefine _7digitshex(h)	_1digitshex((h)>>24),_6digitshex_nocheck(h)
 %xdefine _8digitshex(h)	_1digitshex((h)>>28),_7digitshex_nocheck(h)
 
+%xdefine _5digitssephex(h)	_1digitshex((h)>>16),"_",_4digitshex_nocheck(h)
+%xdefine _6digitssephex(h)	_2digitshex((h)>>16),"_",_4digitshex_nocheck(h)
+%xdefine _7digitssephex(h)	_3digitshex((h)>>16),"_",_4digitshex_nocheck(h)
+%xdefine _8digitssephex(h)	_4digitshex((h)>>16),"_",_4digitshex_nocheck(h)
+
 
 %macro _appenddigitstrdef 2.nolist
 %substr %%ii "0123456789ABCDEF" (%2) + 1
diff --git a/test/lmacros/lmacros2.mac b/test/lmacros/lmacros2.mac
index 717b227..a6a6c83 100644
--- a/test/lmacros/lmacros2.mac
+++ b/test/lmacros/lmacros2.mac
@@ -125,6 +125,9 @@ Intended for 86 Mode programs.
 %else
  %fatal Invalid frame type specified: %1
 %endif
+%ifdef %$parofs
+ %assign %$alignofs %$parofs + %$base_size
+%endif
 %assign %$pars_size 0
 %assign %$pars_return_size 0
 %define %$parlist
@@ -331,6 +334,48 @@ __lvar_list_label %2
  %fatal Must use lframe first
 %endif
 __lvar_define_var %2, %1
+%endmacro
+
+		; Define an alignment variable.
+		; %1	What boundary to align to. Default is 16.
+		; %2	Space to add to align. Default is 0.
+		;
+		; It is assumed that the call instruction that
+		;  called the current function had the stack
+		;  aligned to at least the same boundary.
+		; The second parameter specifies the size of
+		;  any parameters that we want to push before
+		;  doing a call next. The alignment is chosen
+		;  so that the call instruction will get the
+		;  aligned stack.
+		; Sets %$alignment to the size of the variable
+		;  defined for aligning, 0 if none. If not 0,
+		;  the variable ?align_X_Y is defined where X
+		;  is a decimal number indicating the size of
+		;  all prior variables plus r/e/bp on stack
+		;  plus the size set for the frame type, and
+		;  Y is the decimal number of the %2 parameter.
+		; This can only be used if the lframe had a
+		;  frame type other than "none".
+		; If a variable is defined then lreserve or
+		;  another space reservation method must be
+		;  used to actually allocate space for the
+		;  created variable and thus align the stack.
+%imacro lalign 0-2.nolist 16, 0
+%ifctx LENTER
+%elifctx LENTEREARLY
+%elifnctx LFRAME
+ %fatal Must use lframe first
+%endif
+%ifndef %$parofs
+ %fatal Specified no frame type with lframe
+%endif
+%assign %$alignbase %$alignofs - %$ofs
+%assign %$alignadjust %2
+%assign %$alignment (%1 - ((%$alignbase + %$alignadjust) % %1)) % %1
+%if %$alignment
+	lvar %$alignment, align_ %+ %$alignbase %+ _ %+ %$alignadjust
+%endif
 %endmacro
 
 		; Create a defined stack frame.
diff --git a/test/lmacros/lmacros3.mac b/test/lmacros/lmacros3.mac
index d9420a7..be1174e 100644
--- a/test/lmacros/lmacros3.mac
+++ b/test/lmacros/lmacros3.mac
@@ -110,8 +110,10 @@ Intended for 86 Mode programs.
  %error Section %1 not yet added
 %endif
 %if %2
+%define _CURRENT_SECTION
 	[section %1]
 %else
+%xdefine _CURRENT_SECTION %1
 	section %1
 %endif
 	%endmacro
diff --git a/test/lmacros/tests/testalig.asm b/test/lmacros/tests/testalig.asm
new file mode 100644
index 0000000..fd3f697
--- /dev/null
+++ b/test/lmacros/tests/testalig.asm
@@ -0,0 +1,88 @@
+
+%include "lmacros2.mac"
+
+%ifdef _MAP
+[map symbols brief _MAP]
+%endif
+
+	cpu 8086
+	org 100h
+start:
+	and sp, ~15
+	call fun
+	mov word [first], ax
+
+	sub sp, 16 - 4
+	mov cx, 3
+	mov dx, 4
+	 push cx
+	 push dx
+	call fun2
+	 pop ax
+
+	mov word [fifth], ax
+
+	mov ax, 4C00h
+	int 21h
+
+fun:
+	lframe near
+	lenter
+	lvar word, foo
+	lalign 16
+%ifn %$alignment
+ %error Should need alignment
+%endif
+%if %$alignment != 10
+ %error Should need 10-byte alignment
+%endif
+	lreserve
+	lalign 16
+%if %$alignment
+ %error Should not need alignment
+%endif
+	lalign 8
+%if %$alignment
+ %error Should not need alignment
+%endif
+	mov ax, 1
+	test sp, 15
+	jz @F
+	neg ax
+@@:
+	lleave
+	lret
+
+
+fun2:
+	lframe near
+	lpar word, gamma
+	lpar_return
+	lpar word, delta
+	lenter
+	mov ax, [bp + ?gamma]
+	mov word [third], ax
+	mov ax, [bp + ?delta]
+	mov word [fourth], ax
+	mov word [bp + ?gamma], 5
+
+	lalign 16
+%ifn %$alignment
+ %error Should need alignment
+%endif
+%if %$alignment != 12
+ %error Should need 12-byte alignment
+%endif
+	lreserve
+	call fun
+	mov word [second], ax
+
+	lleave
+	lret
+
+	align 256
+first:	dw 0
+second:	dw 0
+third:	dw 0
+fourth:	dw 0
+fifth:	dw 0