⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmacros.new

📁 mas for 8086 microprocessor
💻 NEW
📖 第 1 页 / 共 3 页
字号:
  ;;		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
    n macro
      push s
      push o
    endm
  endm
endif	; ?NOPTR



;;	arg - declare arguements
;;
;;	The given arguments(s) is added to the argument list structure
;;
;;	format:
;;		arg	a
;;
;;	where:
;;		a	is any valid arugment(s) to push
;;
;;	If any element in arglist has not been defined or isn't 16-bit
;;	register, then a compilete specification must have been given in
;;	a text equate and a defx also given (if not, you'll pay the penalty!)
;;

arg macro args
 ifnb <args>
  ifnb ??CM_ArgList
   ??CM_ArgList textequ ??CM_ArgList, <,>, <args>
  else
   ??CM_ArgList textequ <args>
  endif
 endif
endm

;;	?CM_IsIdent - is the arguement a legal identifier?
;;
;;
;; Need to enforce the following additional rules:
;;	Digit may not be first character
;;	Assorted other characters may be used
;;	Dot may be the first character

?CM_IsIdent macro name:REQ
 LOCAL result
 result = 1
 forc char,<name>
  if ('A' LE '&char') AND ('&char' LE 'Z')
   goto next
  endif
  if ('a' LE '&char') AND ('&char' LE 'z')
   goto next
  endif
  if ('0' LE '&char') AND ('&char' LE '9')
   goto next
  endif
  result = 0
  exitm
:next
 endm
 exitm %result
endm


;;	@reverse
;;

@reverse macro list
 LOCAL newlist
 newlist textequ <>
 for x,<list>
  newlist catstr <x>, <,>, newlist
 endm
 ifnb newlist
  newlist substr newlist, 1, @sizestr(%newlist)-1
 endif
 exitm newlist
endm


;;	?ap - process arguments and place onto stack
;;
;;	The given argument is processed (type checking) and placed
;;	on the stack for a pending call.  There must be a type
;;	definition for all arguments (except words).  This can be
;;	done using text equates and the defx macro.
;;

?ap macro n
 ?argl=?argl+2				;; assume one word is pushed
 if 0 EQ (OPATTR n)
  if ?CM_IsIdent(n)
   ifdef n
    n
    exitm
   endif
  endif
% .err <'&n' is not valid to push>
  exitm
 else
  i = (TYPE n)
  if i EQ 1				;; byte type
   push	word ptr(n)
   exitm
  endif  

  if i EQ 2				;; word type
   push	n
   exitm
  endif

  if i EQ 4				;; dword type
   push word ptr (n)[2]
   push word ptr (n)
   ?argl=?argl+2
   exitm
  endif

  if i EQ 8				;; qword type
   push word ptr (n)[6]
   push word ptr (n)[4]
   push word ptr (n)[2]
   push word ptr (n)
   ?argl=?argl+6
   exitm
  endif
  
  push word ptr (n)			;; variable storage
  exitm
 endif
endm


;;	cCall - call a 'c' language procedure
;;
;;	The given procedure is called with the given parameters.  If the
;;	calling convention is C, the arguments are pushed in reverse order,
;;	and removed after the called procedure returns.  If the calling
;;	convention is PL/M, the arguments are pushed as they were encountered,
;;	and the called procedure is assumed to have removed them
;;	from the stack.
;;
;;	The calling convention priority will be:
;;		1) that specified on the cCall if present,
;;		2) that defined by the target,
;;		3) the default (?PLM flag).
;;
;;	format:
;;	    cCall	n,<a>,c
;;
;;	where:
;;	    n	is the name of the procedure to call
;;	    a	are the arguments to be pushed (optional, may be specified
;;		with the "arg" macro.
;;	    c	is the calling convention, C for C, PLM or PASCAL for
;;		PL/M.  The default (?PLM flag) will be used if
;;		not specified).
;;

cCall	macro name:req,args,langType

 ifnb	<args>				;; add any passed in arguments
	arg	<args>			;;   to the list of arguments
 endif					;;   for this procedure

 ifnb	??CM_RegSaveList				;; If there are any resgisters
%	for reg,<??CM_RegSaveList>			;;   to be saved across the call
		push	reg		;;   save then on the stack
	endm				;;
 endif					;;
 
 ifnb	<langType>			;; If a lang type was specified then
  setDefLangType langType		;;   it overrides all common sense
 else
  i = ((OPATTR name) SHR 8) AND 7	;; Get the lang type from the symbol
  if i EQ 0				;; No lang type ---
   setDefLangType			;;   Use the default lang type
  elseif i EQ 1				;; C lang type
   defLangType textequ <C>		;;
  elseif i EQ 4				;; Pascal Lang Type
   defLangType textequ <PASCAL>		;;
  else					;; Unknown lang type
   .err <Unknown lang type specfied for '&name'> ;;
  endif
 endif
 
 ifidn defLangType,<C>			;; If using C calling convention
  ??CM_ArgList textequ @reverse(%??CM_ArgList)	;; then reverse the arguements
 endif					;;

 ?argl=0				;; Clear arguement byte count

% for arg,<??CM_ArgList>			;; Push the procedures arguements
  ?ap <arg>				;;   onto the stack.  ?ap takes
 endm					;;   care of sizing arguements
 
 call name				;; Do the actual call
 
 ifidn defLangType,<C>			;; If this is a C proc and there
  if ?argl NE 0				;;
   add sp,?argl				;;   are parameters then pop them
  endif					;;   off the stack
 endif					;;
 
 ifnb	??CM_RegSaveList				;; If there were any saved registers
  ??CM_RegSaveList textequ @reverse(%??CM_RegSaveList)		;;   then pop them off the stack
%  for reg,<??CM_RegSaveList>			;;   at this point.
   pop	reg				;;
  endm					;;
 endif					;;
 
 ??CM_RegSaveList textequ	<>			;; Clear out the global state
 ??CM_ArgList textequ <>			;;   variable used by the cCall macro
endm



;;	save - flag that the indicated registers are to be saved/restored
;;		on the next cCall invocation
;;
;;	usage:
;;		save <r>
;;
;;	where:
;;		r is the list of registers to be saved.
;;
;;	the macro generates a value for the variable ??CM_RegSaveList
;;

save macro r
 ??CM_RegSaveList textequ <r>
endm

;;	parmX - generate reference to parameter(s) on the stack
;;
;;	usage:
;;		parmX	n
;;	where:
;;		x	is the type of the argument(s) b=byte, w=word, d=dword
;;		n	is the name(s) to be given the parmeter(s).
;;
;;	Byte are considered to be two bytes long for alignment.
;;
;;	The parmd form of the macro generates two equates:
;;
;;		off_name  -	for accessing the offset (lsw) of the parameter
;;		seg_name  -	for accessing the segment (msw) of the parameter
;;

parmB macro names:req
 for name,<names>
  ??CM_addParm <&name:BYTE>
 endm
endm

parmW macro names:req
 for name,<names>
  ??CM_addParm <&name:WORD>
 endm
endm

parmD macro names:req
 for name,<names>
  ??CM_addParm <&name:DWORD>
  ??CM_Paste(off_, name) textequ <word ptr name[0]>
  ??CM_Paste(seg_, name) textequ <word ptr name[2]>
 endm
endm

parmQ macro names:req
 for name,<names>
  ??CM_addParm <&name:QWORD>
 endm
endm

parmT macro names:req
 for name,<names>
  ??CM_addParm <&name:TBYTE>
 endm
endm

if sizec
  parmCP macro n
    parmD <n>
  endm
else
  parmCP macro n
    parmW <n>
  endm
endif

if sized
  parmDP macro n
    parmD <n>
  endm
else
  parmDP macro n
    parmW <n>
  endm
endif


if 0
;;	parmR - register parameter
;;
;;	parmR is the macro used for generating register parameters.
;;	The space allocated for the register parameters will be
;;      the ?ia (interface adjust) area which is between the  old
;;	BP and the first parameter.  Normally this is empty (?ia=0),
;;      or has the saved ds for a windows far procedure.
;;
;;	Byte and dword register parameters will be allowed.
;;
;;      usage:
;;		parmR	n,r,r2
;;      where:
;;              n       is the name of the parameter
;;              r       is the register it is in
;;              r2      is the offset register if a dword


ifndef ?NOPARMR
  .xcref
  .xcref ?pr,parmR
  .cref

  parmR macro n,r,r2
    ?pr n,r,r2,%?rp,%(?ia+2)
  endm

  ;;	?pr - register parameter
  ;;
  ;;	?pr is the actual macro for generating the equates for
  ;;	register parameters.
  ;;
  ;;	usage:
  ;;		parmR	n,r,r2,i,o
  ;;	where:
  ;;		n	is the name of the parameter
  ;;		r	is the register it is in
  ;;		r2	is the offset register if a dword
  ;;		i	is the index of the ?rp to generate
  ;;		o	is the offset from bp where the parm will be

  ?pr macro n,r,r2,i,o
    .xcref
    ifnb <r2>				;;if a dword parameter
      parmR seg_&n,r			;;define segment equate
      parmR off_&n,r2			;;define offset  equate
      n equ (dword ptr [bp-o-2])	;;define dword equate
      .xcref ?t&n
      ?t&n=4				;;show a dword to cmacros
    else
      .xcref ?rp&i
      ?rp&i=0				;;show no register(s)
      ifdef ?&r 			;;define register if valid
	?rp&i=?&r
      endif

      if ??? or (?cpd eq 0) or (?rp&i eq 0)
	??error <invalid parmR encountered: &n,&r>
	exitm
      endif

      n equ (word ptr [bp-o])		;;assume a word register
      ?t&n=2				;;show a word to cmacros
      irp x,<bh,ch,dh,bl,cl,dl,ah,al>
	if ?&&x eq ?&r			;;if really a byte register
	  n equ (byte ptr [bp-o])	;;  then make it a byte
	  ?t&n=1			;;show a byte to cmacros
	  exitm
	endif
      endm
      ?ia=?ia+2 			;;show this guy is out there
      ?rp=?rp+1 			;;show one more register parameter
    endif
    .cref
  endm
endif
endif

localB macro name
 ??CM_addLocal ??CM_Paste(name, <:BYTE>)
endm

localW macro name
 ??CM_addLocal ??CM_Paste(name, <:WORD>)
endm

localD macro name
 ??CM_addLocal ??CM_Paste(name, <:DWORD>)
  off_&name textequ <word ptr name[0]>
  seg_&name textequ <word ptr name[2]>
endm

localQ macro name
 ??CM_addLocal ??CM_Paste(name, <:QWORD>)
endm

localT macro name
 ??CM_addLocal ??CM_Paste(name, <:TBYTE>)
endm

if sizec
  localCP macro n
    localD <n>
  endm
else
  localCP macro n
    localW <n>
  endm
endif

if sized
  localDP macro n
    localD <n>
  endm
else
  localDP macro n
    localW <n>
  endm
endif

localV macro name,a
 local t1
 t1 catstr <name>, < [>, %a, <]:BYTE>
% ??CM_addLocal <t1>
endm


ife ?DF
;;
;;	Define all segments that will be used.  This will allow the
;;	assume and groups to be set up at one given place, and also
;;	allow quick changes to be made
;;

createSeg _TEXT,Code,word,public,CODE
ife ?NODATA
 createSeg _DATA,Data,word,public,DATA,DGROUP
endif
endif

;       errnz exp - generate error message if expression isn't zero
;
;	The errnz will generate an error message if the expression "exp"
;	does not evaluate to zero.  This macro is very useful for testing
;       relationships between items, labels, and data that was coded into
;       an application.
;
;                  errnz   <offset $ - offset label>   ;error if not at "label"
;                  errnz   <eofflag and 00000001b>     ;eofflag must be bit 0
;
;	For expressions involving more than one token, the angle brackets
;       must be used.
;
;	The macro is only evaluated on pass 2, so forward references may be
;       used in the expression.

errnz macro x			;;display error if expression is <>0
 .errnz x
endm

;       errn$ label,exp - generate error message if label (exp) <> $
;
;	The errnz will generate an error message if the label and "exp"
;       does not evaluate to the current value of the location counter.
;	This macro is very useful for testing relationships between
;       labels and the location counter that was coded into an application.
;
;       examples:  errn$   label        ;error if not at "label"
;                  errn$   label,+3     ;error if not three bytes from "label"
;                  errn$   label,-3     ;error if not three bytes past "label"
;
;	If no "exp" is given, it is the same as specifying 0
;
;	The macro is only evaluated on pass 2, so forward references may be
;       used in the expression.

errn$ macro l,x 			;;error if <$-label1 (exp2)> <>0
  errnz   <offset $ - offset l x>
endm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; Extra macros for the c-runtime package
;
; Macro for calling another run-time-library function.
; Does a PUSH CS/CALL NEAR in compact/large models, except
; for QuickC.		--PHG, 5-24-89

callcrt MACRO	funcname
ifdef _QC2
	call	funcname
else
  if sizeC
	push	cs
	call	near ptr (funcname)
  else
	call	funcname
  endif
endif
ENDM

.cref					; Permit symbols to be listed again

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -