📄 cmacros.inc
字号:
;; s is the internal type flag (size), and is one of:
;; word - 2
;; dword - 4
;; byte - 1
;; variable - 0
;; a is a flag indicating that word alignment is to be
;; forced for this type of item.
;;
;; NOTE: It is assumed that the stack is already aligned on a word
;; boundary when the cProc is invoked. The macros will guarantee
;; to allocate an even number of bytes on the stack to maintain
;; word alignment.
?aloc macro n,t,l,s,a
if ?cpd
.xcref
irp x,<n>
???=???+l
if a
???=((??? + 1) and 0fffeh)
endif
?al1 x,<t>,%(???+?ia)
%.xcref ??CM_Paste(?t_,x)
%??CM_Paste(?t_,x)=s
endm
.cref
else
??error <locals "&n" declared outside procedure def>
endif
endm
;; ?al1 - allocate local, continued.
;;
;; ?al1 actually generates the text equate for the local variable.
;; The form of the text equate generated is more or less:
;;
;; name equ (type ptr [bp-?ia-nn])
;; or
;; name equ ([bp-?ia-nn])
;;
;; where:
;; ?ia is defined to be either zero, or is defined to be
;; the number of bytes between the saved BP and the first
;; local. ?ia is only applicable if the current cProc is
;; a windows far procedure or if parmRs have been
;; encountered. If not, the ?ia will be zero. since ?ia
;; is determinable prior to invoking this macro, it will be
;; added into the offset ("nn") passed to this macro
;;
;; usage:
;; ?al1 n,t,o
;; where:
;; n is the name for the text equate
;; t is the type of the equate
;; o is the offset of the equate
?al1 macro n,t,o
n equ (t [bp][-o])
endm
;; ?gcc - get calling convention
;;
;; ?gcv sets the given symbol to the calling convention
;; to be used.
;;
;; usage:
;; ?gcc s,i,cc
;;
;; where:
;; s is the symbol to return the convention in
;; s = 0 if 'C' calling convention
;; s = 1 if PL/M (PASCAL) calling convention
;; i is the initial value for s
;; cc is the calling convention override, and may be one of
;; C use 'C' convention
;; PLM use PL/M calling convention
;; PASCAL use PL/M calling convention
?gcc macro s,i,cc
s = i
ifnb <cc>
ifidn <cc>,<C>
s=0
endif
ifidn <cc>,<PLM>
s=1
endif
ifidn <cc>,<PASCAL>
s=1
endif
endif
endm
ifndef ?NOGLOBAL
.xcref
.xcref globalB,globalW,globalD,globalQ,globalT,globalCP,globalDP
;; globalx - define global data of type x
;;
;; usage:
;; globalx n,i,s,c
;; where:
;; x is the type of the variable b=byte, w=word, d=dword
;; q=quad word, t=tenbytes, cp=code pointer, dp=data pointer
;; n is the name to be given the variable.
;; i is the initial value of the variable.
;; s is the duplication factor
;; c is the convention, C for C, PLM or PASCAL for PL/M.
;; The default (?PLM flag) will be used if not specified.
;;
;; The D form will generate two extra equates of the form off_n and seg_n.
.cref
globalB macro n,i,s,c
?ad <n>,1
?dd n,1,<byte>,<db>,<i>,<s>,<c>
endm
globalW macro n,i,s,c
?ad <n>,2
?dd n,1,<word>,<dw>,<i>,<s>,<c>
endm
globalD macro n,i,s,c
?ad <n>,4
?dd n,1,<dword>,<dd>,<i>,<s>,<c>
off_&n equ word ptr n[0]
seg_&n equ word ptr n[2]
endm
globalQ macro n,i,s,c
?ad <n>,8
?dd n,1,<qword>,<dq>,<i>,<s>,<c>
endm
globalT macro n,i,s,c
?ad <n>,10
?dd n,1,<tbyte>,<dt>,<i>,<s>,<c>
endm
if sizec
globalCP macro n,i,s,c
globalD n,<i>,<s>,<c>
endm
else
globalCP macro n,i,s,c
globalW n,<i>,<s>,<c>
endm
endif
if sized
globalDP macro n,i,s,c
globalD n,<i>,<s>,<c>
endm
else
globalDP macro n,i,s,c
globalW n,<i>,<s>,<c>
endm
endif
endif
ifndef ?NOSTATIC
.xcref
.xcref staticB,staticW,staticD,staticQ,staticT,staticCP,staticDP
;; staticx - define static data of type x
;;
;; usage:
;; staticx n,i,s
;; where:
;; x is the type of the variable b=byte, w=word, d=dword
;; q=quad word, t=tenbytes, cp=code pointer, dp=data pointer
;; n is the name to be given the variable.
;; i is the initial value of the variable.
;; s is the duplication factor
;;
;; statics do not generate an underscored version of the symbol
;; since they are intended to be internal symbols. If they are
;; required to be public, use globlax.
.cref
staticB macro n,i,s
?ad <n>,1
?dd n,0,<byte>,<db>,<i>,<s>,<PLM>
endm
staticW macro n,i,s
?ad <n>,2
?dd n,0,<word>,<dw>,<i>,<s>,<PLM>
endm
staticD macro n,i,s
?ad <n>,4
?dd n,0,<dword>,<dd>,<i>,<s>,<PLM>
endm
staticQ macro n,i,s
?ad <n>,8
?dd n,0,<qword>,<dq>,<i>,<s>,<PLM>
endm
staticT macro n,i,s
?ad <n>,10
?dd n,0,<tbyte>,<dt>,<i>,<s>,<PLM>
endm
if sizec
staticCP macro n,i,s
staticD n,<i>,<s>
endm
else
staticCP macro n,i,s
staticW n,<i>,<s>
endm
endif
if sized
staticDP macro n,i,s
staticD n,<i>,<s>
endm
else
staticDP macro n,i,s
staticW n,<i>,<s>
endm
endif
endif
;; staticx - define static data of type x
;;
;; usage:
;; staticx n,i,s
;; where:
;; x is the type of the variable b=byte, w=word, d=dword
;; q=quad word, t=tenbytes, cp=code pointer, dp=data pointer
;; n is the name to be given the variable.
;; i is the initial value of the variable.
;; s is the duplication factor
;;
;; statics do not generate an underscored version of the symbol
;; since they are intended to be internal symbols. If they are
;; required to be public, use globlax.
?dd macro n,p,t,d,i,s,c
?gcc ?dd2,%?PLM,<c>
ife ?dd2
n label t
?dd1 _&n,p,<d>,<i>,<s>
else
?dd1 n,p,<d>,<i>,<s>
endif
endm
;; ?dd1 is the generalized data definition macro.
;;
;; format:
;; ?dd1 n,p,d,i,s
;; where:
;; n is the name of the procedure
;; p is the public flag
;; d is the assembler directive (db,dw or dd)
;; i is the initial value
;; s is a duplication factor
?dd1 macro n,p,d,i,s
if p
public n
endif
ifb <s>
n d i
else
ifb <i>
n d s dup (?)
else
n d s dup (i)
endif
endif
endm
ifndef ?NOEXTERN
.xcref
.xcref ?ex1,?ex2,externB,externW,externD,externQ,externT
.xcref externNP,externFP,externP,externCP,externDP,externA
.cref
?ex2 = 0
;; externx - define external data of type x
;;
;; usage:
;; externx n,c
;; where:
;; x is the type of the variable b=byte, w=word, d=dword
;; q=quad word, t=tenbytes, cp=code pointer
;; dp=data pointer, a=absolute
;; n is a list of names to define
;; c is the convention, C for C, PLM or PSACAL forPL/M.
;; The default (?PLM flag) will be used if not specified.
externA macro n,c
?ex1 <n>,40h,<abs>,<c>,<>
endm
externB macro n,c
?ex1 <n>,1,<byte>,<c>,<>
endm
externW macro n,c
?ex1 <n>,2,<word>,<c>,<>
endm
externD macro n,c
?ex1 <n>,4,<dword>,<c>,<>
endm
externQ macro n,c
?ex1 <n>,8,<qword>,<c>,<>
endm
externT macro n,c
?ex1 <n>,10,<tbyte>,<c>,<>
endm
externNP macro n,c
?ex1 <n>,2,<near>,<c>,<cc>
endm
externFP macro n,c
?ex1 <n>,4,<far>,<c>,<cc>
endm
if sizec
externP macro n,c
?ex1 <n>,4,<far>,<c>,<cc>
endm
else
externP macro n,c
?ex1 <n>,2,<near>,<c>,<cc>
endm
endif
if sizec
externCP macro n,c
?ex1 <n>,4,<dword>,<c>,<>
endm
else
externCP macro n,c
?ex1 <n>,2,<word>,<c>,<>
endm
endif
if sized
externDP macro n,c
?ex1 <n>,4,<dword>,<c>,<>
endm
else
externDP macro n,c
?ex1 <n>,2,<word>,<c>,<>
endm
endif
;; ?ex1 is the generalized external definition macro
;;
;; format:
;; ?ex1 n,s,d,c,scv
;; where:
;; n is are the names of the externals
;; s is the size in bytes (used for typing)
;; d is the type
;; c is the convention, C for C, PLM or PSACAL for PL/M.
;; The default (?PLM flag) will be used if not specified.
;; scv save calling convention. If this field is "cc", then
;; the calling convention will be saved in a ?CCn equ.
?ex1 macro n,s,d,c,scv
?gcc ?ex2,%?PLM,<c>
irp x,<n>
.xcref
%.xcref ??CM_Paste(?t_,x)
.cref
%??CM_Paste(?t_,x)=s
ife ?ex2
%extrn ??CM_Paste(_,x):&d
%x equ ??CM_Paste(_,x)
else
extrn x:&d
endif
ifidn <scv>,<cc>
.xcref
%.xcref ??CM_Paste(?CC,x)
.cref
%??CM_Paste(?CC,x)=?ex2
endif
endm
endm
endif
ifndef ?NOLABEL
.xcref
.xcref ?lb1,?lblpu,?lb2
.xcref labelB,labelW,labelD,labelQ,labelT
.xcref labelNP,labelFP,labelP,labelCP,labelDP
.cref
?lblpu = 0
?lb2 = 0
;; labelx - define label of data type x
;;
;; usage:
;; labelx n,c
;; where:
;; x is the type of the variable b=byte, w=word, d=dword
;; q=quad word, t=tenbytes, cp=code pointer, dp=data pointer
;; n is a list of names to define, the first of which can
;; be the keyword public
;; c is the convention, C for C, PLM or PSACAL for PL/M.
;; The default (?PLM flag) will be used if not specified.
labelB macro n,c
?lb1 <n>,1,<byte>,<c>
endm
labelW macro n,c
?lb1 <n>,2,<word>,<c>
endm
labelD macro n,c
?lb1 <n>,4,<dword>,<c>
endm
labelQ macro n,c
?lb1 <n>,8,<qword>,<c>
endm
labelT macro n,c
?lb1 <n>,10,<tbyte>,<c>
endm
labelNP macro n,c
?lb1 <n>,2,<near>,<c>
endm
labelFP macro n,c
?lb1 <n>,4,<far>,<c>
endm
if sizec
labelP macro n,c
?lb1 <n>,4,<far>,<c>
endm
else
labelP macro n,c
?lb1 <n>,2,<near>,<c>
endm
endif
if sizec
labelCP macro n,c
?lb1 <n>,4,<dword>,<c>
endm
else
labelCP macro n,c
?lb1 <n>,2,<word>,<c>
endm
endif
if sized
labelDP macro n,c
?lb1 <n>,4,<dword>,<c>
endm
else
labelDP macro n,c
?lb1 <n>,2,<word>,<c>
endm
endif
;; ?lb1 is the generalized label definition macro
;;
;; format:
;; ?lb1 n,s,d
;; where:
;; n are the names of the labels
;; s is the size in bytes (used for typing)
;; d is the type
;; c is the convention, C for C, PLM or PSACAL for PL/M.
;; The default (?PLM flag) will be used if not specified.
?lb1 macro n,s,d,c
?gcc ?lb2,%?PLM,<c>
?lblpu=0
irp x,<n>
ifidn <x>,<PUBLIC>
?lblpu=1
else
.xcref
%.xcref ??CM_Paste(?t_,x)
.cref
%??CM_Paste(?t_,x)=s
ife ?lb2
if ?lblpu
%public ??CM_Paste(_,x)
endif
%??CM_Paste(_,x) label &d
%x equ ??CM_Paste(_,x)
else
if ?lblpu
public x
endif
x label &d
endif
endif
endm
endm
endif
ifndef ?NODEF
.xcref
.xcref defB,defW,defD,defQ,defT,defCP,defDP
.cref
;; defx - inform macros that name is of type x
;;
;; The given name(s) is flaged to be of the given type. This macro
;; is intended for giving types to variables that were not generated
;; by the macros (i.e., static storage). There must be a type definition
;; for all parameters in a call list.
;;
;; usage:
;; defx n
;; where:
;; x is the type of the variable b=byte, w=word, d=dword
;; n is the name(s) to be given the variable(s).
;;
;; Bytes are considered to be two bytes long for alignment reasons
defB macro n
?ad <n>,1
endm
defW macro n
?ad <n>,2
endm
defD macro n
?ad <n>,4
endm
defQ macro n
?ad <n>,8
endm
defT macro n
?ad <n>,10
endm
if sizec
defCP macro n
defD <n>
endm
else
defCP macro n
defW <n>
endm
endif
if sized
defDP macro n
defD <n>
endm
else
defDP macro n
defW <n>
endm
endif
endif
; ?ad is the macro which creates a definition for the given
; symbol
;
; usage:
; ?ad <n>,s
; where:
; n is a list of names to define
; s is the size info (1,2,4,8,10)
?ad macro n,s
irp x,<n>
.xcref
%.xcref ??CM_Paste(?t_,x)
.cref
%??CM_Paste(?t_,x)=s
endm
endm
ifndef ?NOPTR
.xcref
.xcref regPtr,farPtr
.cref
;; regPtr generates information allowing a 32-bit pointer currently
;; in a register to be pushed as a parameter to a subroutine using
;; the cCall macro.
;;
;; usage:
;; regptr n,s,o
;; where:
;; n is the name the argument will be known as
;; s is the register containing the segment portion
;; of the pointer
;; o is the register containing the offset portion
;; of the pointer
;;
;; 2/14/85 - made obsolete with farptr
regPtr macro n,s,o
farPtr n,s,o
endm
;; farPtr generates information allowing a 32-bit pointer to be
;; pushed as a parameter to a subroutine using the cCall macro.
;;
;; usage:
;; farptr n,s,o
;; where:
;; n is the name the argument will be known as
;; s is the segment portion of the pointer
;; o is the offset portion of the pointer
;;
;; Note that any cast must have been made in the argument itself
;; (i.e. regptr ptr1,ds,<word ptr 3[si]>)
farPtr macro n,s,o
.xcref
.xcref ?t_&n
.cref
n macro
push s
push o
endm
?t_&n=80h
endm
endif
;; arg - declare argument
;;
;; The given argument(s) is added to the argument list structure
;;
;; format:
;; arg a
;;
;; where:
;; a is any valid argument to push.
;;
;; If any element in arglist has not been defined or isn't a 16-bit
;; register, then a complete specification must have been given in a
;; text equate and a defx also given (if not, you'll pay the penalty!)
arg macro a
irp x,<a>
?argc=?argc+1
?atal <x>,%?argc
endm
endm
;; ?atal (add to argument list) generates a macro that will cause
;; the given argument to be processed when invoked. It is used by
;; the arg macro only.
?atal macro n,i
.xcref
.xcref ?ali&i
.cref
?ali&i macro
?ap <n>
endm
endm
;; ?ap - process arguments and place onto stack
;;
;; The given argument is processed (type checking) and place on
;; the stack for a pending call. There must be a type definition
;; for all arguments (except words). This can be done by using
;; text equates and the defx macro.
;;
;; format:
;; ?ap n
;; where:
;; n is the name of the argument to be pushed
;;
;; The variable ?argl is updated by the length of the arguments
;; pushed so that the stack can be cleaned up after the call.
?ap macro n
?argl=?argl+2
ifdef ?t_&n
ife ?t_&n-1
push word ptr (n)
exitm
endif
ife ?t_&n-2
push n
exitm
endif
ife ?t_&n-4
push word ptr (n)[2]
push word ptr (n)
?argl=?argl+2
exitm
endif
ife ?t_&n-8
push word ptr (n)[6]
push word ptr (n)[4]
push word ptr (n)[2]
push word ptr (n)
?argl=?argl+6
exitm
endif
if ?t_&n and 80h
n
?argl=?argl+2
exitm
endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -