📄 cmacros.new
字号:
local t2
IF ??CM_state NE 1 ;; Must follow cProc
.err <CMACROS.INC: cBegin must follow a cProc>
endif
??CM_nogen = 0
ifnb <pname>
ifidn <pname>,<nogen>
??CM_nogen = 1
elseifdif ??CM_ProcName, <pname>
% echo <cBegin name (&pname) must match name on preceding cProc (&??CM_ProcName>
endif
endif
??CM_state = 2 ;; Seen a cBegin
% setDefLangType ??CM_langType
macroarg EQU <>
ifnb ??CM_ProcAutoSave
??uses CATSTR <uses >, ??CM_ProcAutoSave
t2 = @InStr(, %??uses, <,>)
while t2 NE 0
??uses CATSTR @SubStr(<%??uses>, 1, %t2-1), < >, @SubStr(<%??uses>, %t2+1)
t2 = @InStr(, %??uses, <,>)
endm
else
??uses textequ <>
endif
ifidn defLangType,<C>
% ??CM_Paste(_, %??CM_ProcName) textequ <??CM_ProcName>
endif
??CM_ProcName proc dist defLangType vis macroarg ??uses ??CM_arg0 ??CM_arg1 ??CM_arg2 ??CM_arg3 ??CM_arg4 ??CM_arg5 ??CM_arg6 ??CM_arg7 ??CM_arg8 ??CM_arg9 ??CM_arg10 ??CM_arg11 ??CM_arg12 ??CM_arg13 ??CM_arg14 ??CM_arg15 ??CM_arg16 ??CM_arg17 ??CM_arg18 ??CM_arg19
??CM_ProcAutoSave EQU <>
t2 = 0
repeat ??CM_localCount
??CM_Paste(??CM_local, %t2)
t2 = t2 + 1
endm
endm
;
cEnd macro pname
IF ??CM_state NE 2 ;; Must follow a cEnd
.err <cEnd must follow a cProc>
endif
??CM_nogen = 0
ifnb <pname>
ifidn <pname>,<nogen>
??CM_nogen = 1
elseifdif ??CM_ProcName, <pname>
% echo <cEnd name (&pname) must match preceeding cProc name (&??CM_ProcName)>
endif
endif
option epilogue:cEpilog
ret
option prologue:prologuedef
option epilogue:epiloguedef
??CM_ProcName endp
??CM_state = 0 ;; not in a function
endm
;
;
cRet macro
IF ??CM_state NE 2 ;; Must follow a cBegin
.err <cRet must follow a cProc>
endif
option epilogue:cEpilog
ret
option epilogue:none
endm
;
; createSeg is a macro that sets up a segment definition and
; a logical name for that segment. The logical name can
; be used to egner the segment, but it cannot be used for anyting
; else.
;
; usage:
; createSeg n, ln, a, co, cl, grp
; where:
; n is the physical name of the segment
; ln is the name it is to be invoked by
; a is the alignment, and is optional
; co is the combine type, and is optional
; cl is the class, and is optional
; grp is the name of the group that contains the segment
;
createSeg macro segName, logName, aalign, combine, class, grp
ifnb <class>
segName segment aalign combine '&class'
else
segName segment aalign combine
endif
segName ends
ifnb <grp>
grp GROUP segName
logName&OFFSET equ offset grp:
logName&BASE equ grp
else
logName&OFFSET equ offset segName:
logName&BASE equ segName
endif
logName&_sbegin macro
segName segment
sEnd macro name
ifnb <name>
ifdifi <name>,<logName>
% echo <sEnd name does not match sBegin logName>
endif
endif
segName ends
purge sEnd
endm
endm
ifnb <grp>
logName&_assumes macro s
assume s:grp
endm
else
logName&_assumes macro s
assume s:segName
endm
endif
endm
sBegin macro name:req
name&_sbegin
endm
; assumes is a macro that will set up the assumes for a segment
; or group created with the createSeg macro. If the assumed
; value passed in isn't known, then a normal assume is made.
;
; usage:
; assumes s,g
;
; where:
; s is the register to make the assumption about
; g is the value to assume is in it
assumes macro s,ln
ifndef ln&_assumes
assume s:ln
else
ln&_assumes s
endif
endm
;
; defGrp
;
defGrp macro foo:vararg
endm
; setDefLangType
setDefLangType macro overLangType
ifnb <overLangType>
ifidn <overLangType>,<C>
defLangType textequ <C>
elseifidn <overLangType>,<PASCAL>
defLangType textequ <PASCAL>
elseifidn <overLangType>,<PLM>
defLangType textequ <PASCAL>
else
% .err <Illegal Language Type specified 'overLangType'>
endif
else ; !nb <overLangType>
if ?PLM EQ 1
defLangType textequ <PASCAL>
elseif ?PLM EQ 0
defLangType textequ <C>
else
.err <Illegal value for ?PLM>
endif
endif ; nb <overLangType>
endm
ifndef ?NOSTATIC
.xcref
.xcref staticB, staticW, staticD, staticQ, staticT, staticCP, staticDP, staticI
.cref
; 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=ten bytes, cp=code pointer,
; dp=data pointer, i=int
; n is the name of the given variable
; i is the initial value of the variable
; s is the duplication factor
;
; statics are always pascal symbols and non-public. If they are required
; to be public then globalX should be used.
staticB macro name:req, initVal:=<?>, repCount
ifnb <repCount>
name db repCount dup (initVal)
else
name db initVal
endif
endm
staticW macro name:req, initVal:=<?>, repCount
ifnb <repCount>
name dw repCount dup (initVal)
else
name dw initVal
endif
endm
staticD macro name:req, initVal:=<?>, repCount
ifnb <repCount>
name dd repCount dup (initVal)
else
name dd initVal
endif
endm
staticI macro name:req, initVal:=<?>, repCount
ifnb <repCount>
name asmI repCount dup (initVal)
else
name asmI initVal
endif
endm
staticQ macro name:req, initVal:=<?>, repCount
ifnb <repCount>
name dq repCount dup (initVal)
else
name dq initVal
endif
endm
staticT macro name:req, initVal:=<?>, repCount
ifnb <repCount>
name dt repCount dup (initVal)
else
name dt initVal
endif
endm
if sizec
staticCP macro name:req, i, s
staticD name,<i>,<s>
endm
else
staticCP macro name:req, i, s
staticW name,<i>,<s>
endm
endif
if sized
staticDP macro name:req, i, s
staticD name,<i>,<s>
endm
else
staticDP macro name:req, i, s
staticW name,<i>,<s>
endm
endif
endif ; ?NOSTATIC
globalB macro name:req, initVal:=<?>, repCount, langType
??CM_gbl1 name, langType, initVal, repCount, DB
endm
globalW macro name:req, initVal:=<?>, repCount, langType
??CM_gbl1 name, langType, <initVal>, repCount, DW
endm
globalD macro name:req, initVal:=<?>, repCount, langType
??CM_gbl1 name, langType, <initVal>, repCount, DD
endm
globalQ macro name:req, initVal:=<?>, repCount, langType
??CM_gbl1 name, langType, initVal, repCount, DQ
endm
globalT macro name:req, initVal:=<?>, repCount, langType
??CM_gbl1 name, langType, initVal, repCount, DT
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
??CM_gbl1 macro name, langType, initVal, repCount:=<1>, kind
setDefLangType langType
ifidn defLangType,<C>
public _&name
name textequ <_&name>
_&name kind repCount dup (initVal)
else
public name
name kind repCount dup (initVal)
endif
endm
ifndef ?NOEXTERN
.xcref
.xcref externB, externW, externD, externQ, externT
.xcref externNP, externFP, externP, externCP, externDP, externA
.cref
; 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=qword, t=tbyte, cp=code pointer, dp=data pointer
; a=absolute, i=int
; n is a list of names to be defined
; c is the lanague convention. C for C or PASCAL or PLM for
; pascal. The default (?PLM flag) will be used if not specified
externA macro names:req, langtype
??CM_ex1 <names>, langtype, ABS
endm
externB macro names:req, langtype
??CM_ex1 <names>, langtype, BYTE
endm
externW macro names:req, langtype
??CM_ex1 <names>, langtype, WORD
endm
externD macro names:req, langtype
??CM_ex1 <names>, langtype, DWORD
endm
externQ macro names:req, langtype
??CM_ex1 <names>, langtype, QWORD
endm
externT macro names:req, langtype
??CM_ex1 <names>, langtype, TBYTE
endm
externNP macro names:req, langtype
??CM_ex1 <names>, langtype, NEAR
endm
externFP macro names:req, langtype
??CM_ex1 <names>, langtype, FAR
endm
if sizec
externP macro n,c
externFP <n>,c
endm
externCP macro n,c
externD <n>,c
endm
else
externP macro n,c
externNP <n>,c
endm
externCP macro n,c
externW <n>,c
endm
endif
if sized
externDP macro n,c
externD <n>,c
endm
else
externDP macro n,c
externW <n>,c
endm
endif
??CM_ex1 macro names, langType, kind
setDefLangType langType
for name,<names>
ifidn defLangType,<C>
name textequ ??CM_Paste(_, name)
extern ??CM_Paste(_, name):kind
else
extern defLangType name:kind
endif
endm
endm
endif ; ?NOEXTERN
ifndef ?NOLABEL
; labelX - define label of data type X
;
labelB macro names:req,langType
??CM_lb1 <names>, langType, BYTE
endm
labelW macro names:req,langType
??CM_lb1 <names>, langType, WORD
endm
labelD macro names:req,langType
??CM_lb1 <names>, langType, DWORD
endm
labelQ macro names:req,langType
??CM_lb1 <names>, langType, QWORD
endm
labelT macro names:req,langType
??CM_lb1 <names>, langType, TBYTE
endm
labelNP macro names:req,langType
??CM_lb1 <names>, langType, NEAR
endm
labelFP macro names:req,langType
??CM_lb1 <names>, langType, FAR
endm
if sizec
labelP macro n,c
labelFP <n>,c
endm
labelCP macro n,c
labelD <n>,c
endm
else
labelP macro n,c
labelNP <n>,c
endm
labelCP macro n,c
labelW <n>,c
endm
endif
if sized
labelDP macro n,c
labelD <n>,c
endm
else
labelDP macro n,c
labelW <n>,c
endm
endif
??CM_lb1 macro names:req, langType, kind
setDefLangType langType
?pu = 0
for name,<names>
ifidn <name>,<PUBLIC>
?pu =1
else
ifidn defLangType,<C>
if ?pu
public ??CM_Paste(_, name)
endif
name textequ ??CM_Paste(_, name)
??CM_Paste(_, name) label kind
else
if ?pu
public name
endif
name label kind
endif
endif
endm
endm
endif ; ?NOLABEL
ifndef ?NODEF
; defX - inform the macros that name is of type X
;
; The given name(s) is flagged to be of the given type.
;
; This macro is no longer needed.
;
for lbl,<defB, defW, defD, defQ, defT, defCP, defDP>
lbl macro names:req
endm
endm
endif ; ?NODEF
ifndef ?NOPTR
;; 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -