I have spent the last couple of weeks writing a new installation for the next version of MASM32, testing it and making sure it installs OK, added all the newer tools, rationalised the examples while adding new ones and have added a completely new set of include files that have direct UNICODE support. With special thanks to Ramon Sala who matched the WINDOWS.INC to the new include files, the main WINDOWS.INC and the rest of the include files respond to defining "__UNICODE__" and will use the UNICODE versions of API calls instead of the default ANSI API functions. Now I have it reasonably well tested on ANSI code but have done very little testing on UNICODE functions.
What I need is the assistance of some of our more experienced members in testing the installation and checking if it all works on other peoples computer configurations. It installs correctly on Win2000, WinXP SP3 and Win7 64 bit but noting that these test machines are configured properly for development and are not obstructed by either OS settings or AV scanners.
I have yet to do any real work on the libraries and documentation and this also must be done but what I need at the moment is a number of experienced people who can help with the testing of this new version. If you have the time would you let me know and I will send you the link to the BETA version. i have not directly posted the link as I don't want to have to wade through a pile of noise, nonsense and garbage, I actually need some assistance from people who know what they are doing.
Ok to test it on:
Intel(R) Celeron(R) CPU 2.80GHz
Microsoft Windows XP Professional Build Service Pack 3 2600
send me the link.
give it by personal message of the forum
No problem,it's work for me
hi Hutch,
Have you update the unicode macros (bug)? Also there was a bug in the cmd$ macros (http://www.masm32.com/board/index.php?topic=16907.0).
Just seeing that you have introduce the __UNICODE__ equate, you may want also change the string support of the fn,rv,... macros -> means, that they produce a unicode strings if __UNICODE__ is defined?
Alternatively it may be useful to have the the 'L' prefix (like in c/c++) for strings - I've allready written my own fn/rv macros with these feature.
qWord
EDIT:
In the attachment the extended fn and rv macros. The syntax is:
unicode:
fn function,...,L'xyz',...,L"'quoted'"
ascii:
fn function,...,"xyz",...,'"double quoted"'
The same applies for rv(). Additional there are some high level features:
Insted of ADDR/OFFSET you can shortly prepend a '&' (as in c/c++):
fn function,&sz[0],...
Also for both, fn and rv, a optional destination can be placed in front of the function name:
fn dest32 = function,...
.if rv(dest2=myFunction,...)
These two features can of course be removed - they may be a bit to 'high' for some people :bg
Yves,
Thanks, your help is much appreciated.
qWord,
I have not yet done any real work on the libraries or the macros but I a wary of changing any of the stuff that has been around for a long time as it may break existing code that people have already written. I don't fully understand the macros you have written but they look interesting and if they can be made general purpose enough I don't see any reason not to name them slightly differently and include them as well. What I do need with macros is some documentation so I know what they do and so that programmers can predictably use them.
Quote from: hutch-- on October 05, 2011, 11:27:27 AMI don't fully understand the macros you have written but they look interesting and if they can be made general purpose enough I don't see any reason not to name them slightly differently and include them as well. What I do need with macros is some documentation so I know what they do and so that programmers can predictably use them.
ok, I will work on these macros and their documentation the next days.
hi,
here are the macros. Just to make clear my naming convention for equates and textmacros: to make them unique I allways use the macros name, or an abbreviation of it, as a prefix.
AFAICS, they are full compatible with the current fn and rv macros, thus they should not break with existing code...
;/********************************************************************/
;/* fn - macro procedure */
;/* This macro enhanced the INVOKE-directive: */
;/* - It adds support for quoted ASCII or unicode strings. */
;/* The strings can be either enclosed by double quotes or by */
;/* single quotation marks. Unicode strings are declared by */
;/* using the 'L'-prefix: */
;/* ASCII: "my string" or 'my string' */
;/* Unicode: L"my string" or L'my string' */
;/* MASM's reserved characters like exclamation marks, angel */
;/* brackets and single brackets [,...] can not be used. */
;/* - ADDR-expressions can be shorten by using a ampersand '&': */
;/* fn MessageBoxW,0,&wsz[0],L'xyz',0 */
;/* - a optional destination can be specified in front of the */
;/* function: */
;/* fn dest=FncName,... */
;/* */
;/* Example: */
;/* fn MessageBox,0,"my string",&wsz[0],0 */
;/* fn hWnd = CreateWindowEx,... */
;/* qWord, 2011 */
;/********************************************************************/
fn macro FncName:req,args:VARARG
;/* check if a optional destination is specified */
fnex_flag = 0
IF @InStr(1,<&FncName>,<=>)
fnex_flag = 1
fnex_dest SUBSTR <&FncName>,1,@InStr(1,<&FncName>,<=>)-1
fnex_arg TEXTEQU <invoke >,@SubStr(<&FncName>,@InStr(1,<&FncName>,<=>)+1)
ELSE
fnex_arg TEXTEQU <invoke FncName>
ENDIF
;/* process argument list and append it to the invoke-call */
fnex_arg CATSTR fnex_arg,repargs(&args)
;/* place the function call */
fnex_arg
;/* if available, fill the specified destination */
IF fnex_flag EQ 1
mov fnex_dest,eax
ENDIF
endm
;/********************************************************************/
;/* rv - macro function */
;/* This macro is the function-version of the fn-macro. */
;/* */
;/* Example: */
;/* mov edi,rv(myFunction,L"my string",&wsz[0],...) */
;/* .break .if !rv(dest=myFunction,...) */
;/* qWord, 2011 */
;/********************************************************************/
rv macro FncName:req,args:VARARG
;/* check if a optional destination is specified */
rvex_flag = 0
IF @InStr(1,<&FncName>,<=>)
rvex_flag = 1
rvex_dest SUBSTR <&FncName>,1,@InStr(1,<&FncName>,<=>)-1
rvex_arg TEXTEQU <invoke >,@SubStr(<&FncName>,@InStr(1,<&FncName>,<=>)+1)
ELSE
rvex_arg TEXTEQU <invoke FncName>
ENDIF
;/* process argument list and append it to the invoke-call */
rvex_arg CATSTR rvex_arg,repargs(&args)
;/* place the function call */
rvex_arg
;/* if available, fill the specified destination */
IF rvex_flag EQ 1
mov rvex_dest,eax
ENDIF
EXITM <eax>
endm
;/*******************************************************************/
;/* simplwsz , macro procedure */
;/* Creates a zero terminated Unicode string in current segment. */
;/* Parameters: */
;/* lbl : The label/name of the string */
;/* txt : string, either enclosed by single quotation marks */
;/* or by double quotes. You cannot use MASM's */
;/* reserved characters like exclamation marks, */
;/* angel brackets, single brackets,... . */
;/* <""> or <''> cause the cration of an empty string. */
;/* Return: an error is indicated by setting the equate */
;/* smplwsz_error to 1 */
;/* Example: */
;/* .data */
;/* simplwsz myLabel,"unicode 123'4" */
;/* IF smplwsz_error */
;/* ;; error */
;/* ELSE */
;/* ;; OK, no error */
;/* ENDIF */
;/* .code qWord, 2011 */
;/*******************************************************************/
simplwsz macro lbl:req,txt:req
smplwsz_error = 0
;/* remove leading blanks (trim) */
FOR arg,<&txt>
simplwsz_arg TEXTEQU <&arg>
EXITM
ENDM
;/* exit if argument is blank */
IFB simplwsz_arg
smplwsz_error = 1
EXITM
ENDIF
simplwsz_pos1 INSTR 1,simplwsz_arg,<">
simplwsz_pos2 INSTR 1,simplwsz_arg,<'>
align 2
lbl LABEL WORD
;/* check wether the string is enclosed by */
;/* double quotes or by single quotation marks */
IF simplwsz_pos1 EQ 1
;/* loop through all cahr. after removing the enclosing */
;/* double quotes */
% FORC char,<@SubStr(%simplwsz_arg,2,@SizeStr(%simplwsz_arg)-2)>
dw "&char"
ENDM
ELSEIF simplwsz_pos2 EQ 1 */
% FORC char,<@SubStr(%simplwsz_arg,2,@SizeStr(%simplwsz_arg)-2)>
dw '&char'
ENDM
ELSE
;/* invalid argument *
smplwsz_error = 1
ENDIF
;/* term. zero */
dw 0
EXITM
endm
;/*****************************************************************/
;/* repargs , macro function */
;/* Parse the arguments list 'args' and replace: */
;/* - String literals by the corresponding OFFSET-expression */
;/* after creating an anonym string in the .data-section */
;/* - leading ampersands (&) by the ADDR operator */
;/* All other arguments are left untouched. */
;/* */
;/* Details: */
;/* This macro allows using ASCII and Unicode strings. */
;/* Unicode strings are defined by using the 'L'-Prefix: */
;/* L"my unicode string" or L'my "quoted" string' */
;/* Furthermore, ampersands are replaced by <ADDR >, if they */
;/* are the first character of the argument: */
;/* ..., &sz[0],... -> ..., ADDR sz[0],... */
;/* */
;/* Return: */
;/* The processed argument list. If a nonempty list is passed */
;/* to the macro, the returned list is always leaded */
;/* by a comma: */
;/* <arg1,arg2,...> -> <,newArg1,newArg2,...> */
;/* The number of arguments in list is stored in */
;/* the equate repargs_cntr. */
;/* */
;/* Remarks: */
;/* This macro is designed to process arguments lists for */
;/* the INVOKE-directive. */
;/* The macro assumes to be called from the .code-section */
;/* */
;/* Example: */
;/* invk_txt TEXTEQU <invoke FncName> */
;/* invk_txt CATSTR invk_txt,repargs(ArgumentList) */
;/* invk_txt */
;/* qWord, 2011 */
;/*****************************************************************/
repargs macro args:VARARG
;/* initialize global counter, which */
;/* is used for label-creation. */
IFNDEF repargs_glb_cntr
repargs_glb_cntr = 0
ENDIF
repargs_cntr = 0
repargs_args TEXTEQU <>
FOR arg,<&args>
repargs_txt TEXTEQU <&arg>
;/* analyze current argument */
repargs_pos1 INSTR 1,<&arg>,<">
repargs_pos2 INSTR 1,<&arg>,<'>
repargs_pos3 INSTR 1,<&arg>,<L">
repargs_pos4 INSTR 1,<&arg>,<L'>
repargs_pos5 INSTR 1,<&arg>,<!&>
IF repargs_pos1 EQ 1 OR repargs_pos2 EQ 1
;/* create ASCII string */
.data
IF @SizeStr(<%repargs_txt>) GT 2
@CatStr(<$$_szlbl_>,%repargs_glb_cntr) db repargs_txt,0
ELSE
@CatStr(<$$_szlbl_>,%repargs_glb_cntr) db 0
ENDIF
.code
repargs_args TEXTEQU repargs_args,<,OFFSET $$_szlbl_>,%repargs_glb_cntr
repargs_glb_cntr = repargs_glb_cntr + 1
ELSEIF repargs_pos3 EQ 1 OR repargs_pos4 EQ 1
;/* remove 'L'-prefix */
repargs_txt SUBSTR repargs_txt,2
;/* create Unicode string */
.data
IF @SizeStr(<%repargs_txt>) GT 2
simplwsz @CatStr(<$$_wszlbl_>,%repargs_glb_cntr),<%repargs_txt>
ELSE
@CatStr(<$$_wszlbl_>,%repargs_glb_cntr) dw 0
ENDIF
.code
repargs_args TEXTEQU repargs_args,<,OFFSET $$_wszlbl_>,%repargs_glb_cntr
repargs_glb_cntr = repargs_glb_cntr + 1
ELSEIF repargs_pos5 EQ 1
;/* replace '&' with <ADDR > and append argument to list */
repargs_args TEXTEQU repargs_args,<,>,<ADDR >,@SubStr(%repargs_txt,2,)
ELSE
;/* record unprocessed argument */
repargs_args TEXTEQU repargs_args,<,>,repargs_txt
ENDIF
repargs_cntr = repargs_cntr + 1
ENDM
EXITM repargs_args
endm
qWord,
These look very useful but I am inclined to see them as extended capacity and would prefer them to be slightly renamed so that the originals are still available. The suggestion is to use "rvx" for extended capacity and "fnx" for the function version.
Now i have a question, would it be possible to modify the macros so they responded to the the UNICODE equate,
__UNICODE__ equ 1 ; enable UNICODE API functions
I think this would be more useful than prefixing the quoted string with L"quoted text" and it would mean that the same code could be built in both ANSI and UNICODE formats.
I like the leading "&" notation option and imagine that many people will be pleased with the convenience of having it available.
The logic in the new include files switches the API calls based on the equate __UNICODE__ and looks basically like this.
AppendMenuA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD
IFNDEF __UNICODE__
AppendMenu equ <AppendMenuA>
ENDIF
AppendMenuW PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD
IFDEF __UNICODE__
AppendMenu equ <AppendMenuW>
ENDIF
What the request was aimed at was using this logic to switch between ANSI and UNICODE string output simply by defining the equate.
Quote from: hutch-- on October 06, 2011, 06:52:16 PMNow i have a question, would it be possible to modify the macros so they responded to the the UNICODE equate,
yes, it possible to create Unicode if the equate is defined( or its value is non-zero?). However, I would suggest to keep also the L-prefix, such it is possible to force unicode strings. This would be useful for situations, where mainly ASCII is used, but a few functions need unicode strings (e.g.: if you work with GDI+).
What do think about some new macros for creating Unicode strings?:
The current available macros, WSTR ans uni$, are very limited in their function. For example you can only create zero terminated strings, thus it is not possible to create strings over more than one line. Also they are limit to 118 char. and they can not be used with the SIZEOF and LENGTHOF operator.
I'm using macros , which allows declaration of strings (and C-Strings) with the same syntax as the DB-directive. This macros could be easily ported to masm32.
hi,
I've adapted the macros, so that they work with __UNICODE__ equate:
If the equate is defined and has a nonzero value, unicode strings are created. Otherwise ASCII strings are created. The L-prefix is still available, thus you can force Unicode string creation.
I've also renamed the rv/fn-macros and added 4 new macros for string creation:
UCSTR and uc$() -> allows declaration like MASM's DB-directive.
UCCSTR and ucc$() -> the same as UCSTR/uc$, but adds support for escape sequences
Can you send me a copy of the new package, so that I can make some test?
regards, qWord
hi hutch--,
In the attachment the file with working macros (AFAICS) and two examples:
UCSTR / uc$() -> unicode string , dependencies: none
UCCSTR / ucc$() -> unicode string + escape sequences, dependencies: none
UC TEXTEQU <UCSTR>
UCC TEXTEQU <UCCSTR>
The macros uc$ and ucc$ are creating zero terminated strings. The returned labels (all macros) can be used with the SIZEOF and LENGTHOF operator.
fnx / rvx() -> function call, dependencies: smplwsz, repargs(), UC_PREFIX
smplwsz -> unicode string, single argument, dependencies: none
qWord
Thanks, I will set them up for testing and come back to you. :U
XP Mce2005 Sp3
Hello World
This is a MASM32's uicode support test.
next line
"quoted text"
This is a C-String!
()<>\
This Text
needs
four
lines
!!!
major bug !!!! - the "n" is missing in "unicode" :bg
(http://www.masm32.com/board/index.php?action=dlattach;topic=17481.0;id=9810)
i suppose i need to have some foreign character set installed ?
Quote from: dedndave on October 10, 2011, 04:30:40 AM
i suppose i need to have some foreign character set installed ?
yes :-)
(http://www.masm32.com/board/index.php?action=dlattach;topic=17481.0;id=9811)
Many fonts are good[tm] for you.
(http://www.masm32.com/private/muling.jpg)
qWord,
I have been playing with the idea of prefixes as you designed the macro that uses them, I thought it would be a good idea to add the indirection operator as well so that you have both REFERENCE and DEREFERENCE as prefix operators.
I have a working test piece that is doing this OK on the generic macros for MASM32,
; -------------
; expand prefix
; -------------
expand_prefix MACRO txtitm
LOCAL prefix1,wrd,nu,varname
prefix1 SUBSTR <txtitm>,1,1
;; usable characters are "&" "*" "@" "#" "?" "^" "~" "`" "/"
IFIDN prefix1,<&> ;; reference operator
nu SUBSTR <txtitm>,2
wrd CATSTR <ADDR >,nu
EXITM <wrd>
ENDIF
IFIDN prefix1,<*> ;; indirection operator
nu SUBSTR <txtitm>,2
IF op_type(nu) eq 5 ;; if its a register
mov nu, [nu]
EXITM <nu>
ELSE
.data?
varname dd ?
.code
push ebx
mov ebx, nu
mov ebx, [ebx] ;; dereference variable in EBX
mov varname, ebx
pop ebx
EXITM <varname>
ENDIF
ENDIF
EXITM <txtitm> ;; exit with original argument
ENDM
Notation example is as follows.
fn MessageBox,0,*parr,&titletxt,MB_OK
Now another comment, the macros that were in WINDOWS.INC should not have been there, specifically the ones that specify ASCII or UNICODE. I remember that you had written your own and this would be useful in supporting your new macro system where you use prefixes to force either ASCII or UNICODE if desired. There is a limited range of single characters available to use as prefixes but it is worth avoiding single alphabetic characters for clarity reasons, it makes sense to use the "?" character as the UNICODE prefix as it mirrors what UNICODE displays in ASCII. For the reverse when forcing ASCII, an ordinary macro would do the job.
ascii MACRO quoted_text
LOCAL txtname
.data
txtname db quoted_text,0
.code
EXITM <OFFSET txtname>
ENDM
Let me know what you think.
Good idea to add a set of macros to simplify pointers usage.
Perhaps this ones can be of some use.
http://www.masm32.com/board/index.php?topic=17351.msg145740#msg145740
They replace the assume directive and act as c++ with the pointed data.
start idea is simple.
Quote
DECLARE_pointer TEXTEQU <MyStruct>
and the macros do what is needed to move and adress data.
here a sample of use
http://www.masm32.com/board/index.php?topic=17108.msg145682#msg145682
Another sample is this macro
Quote
;add: DECLARE_pointeur TEXTEQU <STInterFace>
;where pointeur is
; pointeur dd ;all name who get the com pointer
; USAGE:
; COM pointeur,Release ;usefull with duplicate pointer
COM MACRO ppv:REQ,fonction:REQ,args:VARARG
local InvokeInterface
computeoffset CATSTR <DECLARE_>,<ppv>
;---------- controle les arguments
FOR arg, <args> ;verifier que edx n'est pas dans la liste d'arguments args
IFIDNI <&arg>, <edx> ;
.ERR <edx is not allowed as a coinvoke parameter>
ENDIF
ENDM
IFIDNI <&pInterface>, <edx>
.ERR <edx is not allowed as a coinvoke parameter>
ENDIF
;------------ --------------------------------
;InvokeInterface = concatene ...CATSTR(concatene) MACRO instruction MASM32
;---------------------------------------------
InvokeInterface CATSTR <invoke (computeoffset ptr [edx]).>,<&fonction,ppv>
IFNB <args> ; add the list of parameter arguments if any
InvokeInterface CATSTR InvokeInterface, <, >, <&args>
ENDIF
; -----------------------
mov edx, ppv
mov edx, [edx]
InvokeInterface
ENDM
hutch,
do you think it make really sense to use the fnx/rvx macros, whereas these new features could be simply added to the existing fn[c]/rv[c] macros? IMO this would make the macro interface more uniform.
Adding support for the L-prefix, referencing and dereferencing wouldn't break existing code - regardless this, we could include an equate like 'MASM32_V10_COMPATIBLE', which force the old macro definition.
To your previous post: Did I understand you right: you want to use '?' as a unicode prefix? In context to your nice idea of the c/c++ dereferencing-operator (and it counterpart '&'), it would break the macro's syntax consistency (IMO).
To the implementation of the dereferencing-operator: I would use the stack instead of a global variable because it is thread save and probably faster (the stack is cached). Also overwriting any registers is not a good attitude :bg
Here an example how I would solve 'dereferencing':
; nParam = number of function arguments
; iParam = current argument index (zero-based)
; txtitm = argumetn to check
expand_prefix MACRO nParam,iParam,txtitm
expprfx_prefix SUBSTR <txtitm>,1,1
IFIDN expprfx_prefix,<&> ;; reference operator
expprfx_arg SUBSTR <txtitm>,2
% EXITM <ADDR &expprfx_arg>
ENDIF
IFIDN expprfx_prefix,<*> ;; indirection operator
expprfx_arg SUBSTR <txtitm>,2
IF op_type(%expprfx_arg) eq 5 ;; if its a register
mov expprfx_arg, [expprfx_arg]
% EXITM <DWORD ptr [&expprfx_arg]>
ELSE
mov eax,expprfx_arg
mov eax,[eax]
mov DWORD ptr [esp-2*nParam*4+iParam*4],eax ;; store argument on stack
EXITM <DWORD ptr [esp-nParam*4-4]> ;; return esp-relativ argument for INVOKE-directive
ENDIF
ENDIF
EXITM <txtitm> ;; exit with original argument
ENDM
fn MACRO FuncName:REQ,args:VARARG
p@args equ <invoke FuncName> ;; construct invoke and function name
n@args = argcount(args) ;; get number of arguments
i@args = 0
FOR var,<args> ;; loop through all arguments
p@arg TEXTEQU reparg(var) ;; replace quotes
p@arg TEXTEQU expand_prefix(%n@args,%i@args,%p@arg) ;; replace special operators
p@args CATSTR p@args,<,>,p@arg ;; p@args + <,> + p@arg
i@args = i@args + 1 ;; update argument index
ENDM
p@args ;; write the invoke macro
ENDM
The "rv", "fn, "rvc" and "fnc" macros have all been rewritten to handle both ASCII and UNICODE and are working in a reliable manner and they must stay independent as they are used by a large number of other macros. I wanted to keep your "rvx" and "fnx" as separate extended versions so that the programmer has the choice of which version they use but I would like to see a C escape version of both as well which is easy enough to do. One other thing, the C escapes should support "\0" as well for embedded nulls in string like those that are used for common dialogs for file types and extensions. "All Files\0*.*\0\0".
You are right about overwriting the register and I had already removed it, I will have a look at the stack technique you have used but I have no problem using a macro LOCAL variable that ends up in the data section as each is unique and therefore thread safe.
Now just a quick look at the macro and you are overwriting EAX which can cause problems wit following arguments that are returned in EAX. I did not want any of the compound macros to overwrite any register, that is why I used the unique data section variable.
Quote from: hutch-- on October 25, 2011, 12:50:36 AMI wanted to keep your "rvx" and "fnx" as separate extended versions so that the programmer has the choice of which version they use but I would like to see a C escape version of both as well which is easy enough to do. One other thing, the C escapes should support "\0" as well for embedded nulls in string like those that are used for common dialogs for file types and extensions. "All Files\0*.*\0\0".
OK - I will send you the new macros
fnx[
c]/
rvx[
c] the next days, which will have following features:
-
L-prefix for Unicode strings (should work, because you have removed the L-macros from windows.inc)
- string creation according to __UNICODE__-equate
-
A-prefix to force ASCII strings, even if __UNICODE__ is defined
- reference
& - dereference
* - optional, additional assignment using
=Also I will update the UCCSTR -macros to support
\0.
Quote from: hutch-- on October 25, 2011, 01:50:33 AM
Now just a quick look at the macro and you are overwriting EAX which can cause problems wit following arguments that are returned in EAX. I did not want any of the compound macros to overwrite any register, that is why I used the unique data section variable.
no problem: eax can also saved on the stack: mov
DWORD ptr [esp-4],eax ...
mov eax,DWORD ptr [esp-4] :bg
qWord,
For the C escape versions, name them "rvcx" and "fncx" so they are consistent with the existing names. What I want to be able to provide is the generic versions and the extended versions as two separate systems so the user can select which method they want to use with either being dependent on the other. I need these for the next BETA as I have already done most of the documentation for the new extended system and I will need to change that before the next BETA.
hi,
In the attachment the new macros and updated examples.
What has changed (this may be importend for the documentation):
- the fncx and rvcx macros were added
- \0 - escape sequence added (UCCSTR/ucc$, rvcx/fncx)
- the Unicode prefix has been change from u to L (rv[c]x/fn[c]x. The L()-macro, which was placed in Windows.inc must be deleted)
- A-prefix added to force ASCII strings (rv[c]x/fn[c]x)
- *-operator added to rv[c]x/fn[c]x , thread safe , only pointers to DWORDs can be dereferenced
- a new macro for internal purpose is added: ?cstr? -> ASCII c-strings, syntax-compatible to UCCSTR
- the repargs-macro has a new, additional argument, which allows to enable support for c-strings. Also this macro has been modified according to the changes in the macros rv[c]x and fn[c]x
- some small changes to the examples
You should replace all macros I've supplied.
regards, qWord
Excellent, I will unzip it, replace the earlier ones in macros.asm and perform the changes to the documentation.