;*DDK*************************************************************************/
;
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
; rmacros.inc by Alex Pollitt 28/4/91

; version 2.0 by Alex Pollitt 16/5/91



IF1

reglist equ <eax, ebx, ecx, edx, ebp, esi, edi,\
ax, bx, cx, dx, bp, si, di,\
ah, al, bh, bl, ch, cl, dh, dl,\
eax_top, ebx_top, ecx_top, edx_top, ebp_top, esi_top, edi_top, dmy>
Reglist equ <EAX, EBX, ECX, EDX, EBP, ESI, EDI,\
AX, BX, CX, DX, BP, SI, DI,\
AH, AL, BH, BL, CH, CL, DH, DL,\
EAX_TOP, EBX_TOP, ECX_TOP, EDX_TOP, EBP_TOP, ESI_TOP, EDI_TOP>

ebpsubs equ <ebp_top, bp>
esisubs equ <esi_top, si>
edisubs equ <edi_top, di>
eaxsubs equ <eax_top, ax, ah, al>
ebxsubs equ <ebx_top, bx, bh, bl>
ecxsubs equ <ecx_top, cx, ch, cl>
edxsubs equ <edx_top, dx, dh, dl>
axsubs equ <ah, al>
bxsubs equ <bh, bl>
cxsubs equ <ch, cl>
dxsubs equ <dh, dl>

siadds equ <esi>
diadds equ <edi>
bpadds equ <ebp>
axadds equ <eax>
aladds equ <eax, ax>
ahadds equ <eax, ax>
bxadds equ <ebx>
bladds equ <ebx, bx>
bhadds equ <ebx, bx>
cxadds equ <ecx>
cladds equ <ecx, cx>
chadds equ <ecx, cx>
dxadds equ <edx>
dladds equ <edx, dx>
dhadds equ <edx, dx>
eax_topadds equ <eax>
ebx_topadds equ <ebx>
ecx_topadds equ <ecx>
edx_topadds equ <edx>
esi_topadds equ <esi>
edi_topadds equ <edi>
ebp_topadds equ <ebp>

alalso equ <eax_top, ah>
ahalso equ <eax_top, al>
blalso equ <ebx_top, bh>
bhalso equ <ebx_top, bl>
clalso equ <ecx_top, ch>
chalso equ <ecx_top, cl>
dlalso equ <edx_top, dh>
dhalso equ <edx_top, dl>
axalso equ <eax_top>
bxalso equ <ebx_top>
cxalso equ <ecx_top>
dxalso equ <edx_top>
sialso equ <esi_top>
dialso equ <edi_top>
bpalso equ <ebp_top>
eax_topalso equ <ax, ah, al>
ebx_topalso equ <bx, bh, bl>
ecx_topalso equ <cx, ch, cl>
edx_topalso equ <dx, dh, dl>
esi_topalso equ <si>
edi_topalso equ <di>
ebp_topalso equ <bp>

outputErrorOnAnyPass macro description
 if1
  .err description
  %out rmacros pass-1 error  :  description
 endif
 if2
  outputError <&description>
 endif
endm

outputError macro description
 if2
  .err description
  %out e r r o r  :  description
 endif
endm

getBigReg macro reg, reglist, Reglist
 i = 0
 irp r, <&reglist>
  ifidn <r>, <reg>
   exitm
  endif
  ifidn <r>, <dmy>
   outputError <rmacros does not recognise reg as a register>
   exitm
  endif
  i = i + 1
 endm
 j = 0
 irp r, <&Reglist>
  if i eq j
   Reg equ <r>
   exitm
  endif
  j = j + 1
 endm
endm

set macro name, something
 name equ <something>
; if2
;  %out name = something
; endif
endm

append macro d, s1, s2
 d equ <s1, s2>
endm

checkRegNotUsed macro reguse, reg, Reg
 ifdif <reguse>, <Reg>
  outputError <reg is already in use: reguse>
 endif
endm

checkRegSubsNotUsed macro regsubs
 irp reg, <&regsubs>
  getBigReg reg, %reglist, %Reglist
  ifdef &reg
   checkRegNotUsed % &reg, reg, %Reg
  endif
 endm
endm

checkNameNotUsed macro nameuse, name
 ifdif <nameuse>, <name&_not_in_use>
  outputError <name is already in use with nameuse>
 endif
endm

nameRegSubs2 macro reg, name
 getBigReg reg, %reglist, %Reglist
 reg equ <reg&_in_use_for_&name>
 set reg&name, %Reg
 append reg&namelist, % reg&namelist, name
endm

nameRegSubs macro regsubs, name
 irp reg, <&regsubs>
  nameRegSubs2 reg, name
 endm
endm

nameRegAdds2 macro reg, name
 getBigReg reg, %reglist, %Reglist
 reg equ <reg&_in_use_for_&name>
endm

nameRegAdds macro regadds, name
 irp reg, <&regadds>
  nameRegAdds2 reg, name
 endm
endm

rName macro reg, name
 checkStatusIs %status, <started>
 getBigReg reg, %reglist, %Reglist
 ifdef &reg
  checkRegNotUsed %&reg, reg, %Reg
 endif
 ifdef &name
  checkNameNotUsed %&name, name
 endif
 reg equ <reg&_in_use_for_&name>
 set reg&name, %Reg
 set name, %Reg
 append reg&namelist, % reg&namelist, name
 addNameToNameListAorB name, %whichlist
 ifdef reg&subs
  nameRegSubs % reg&subs, PartOf&name
 endif
 ifdef reg&adds
  nameRegAdds % reg&adds, name&_partly
 endif
endm

addNameToNameListAorB macro name, wlist
 ifidn <wlist>, <A>
  append namelistA, name, %namelistA
  set whichlist, <B>
 else
  append namelistB, name, %namelistB
  set whichlist, <A>
 endif
endm

checkRegUse macro reguse, reg, name
 ifdif <reguse>, <reg&_in_use_for_&name>
  outputError <reg is is not in use for name: reguse>
 endif
endm

checkNameUse macro nameuse, name, reg
 ifdif <nameuse>, <reg>
  outputError <name is in use for nameuse>
 endif
endm

clearRegSubsUse2 macro reg, name
 getBigReg reg, %reglist, %Reglist
 set reg, %Reg
 set reg&name, <name&_not_in_use>
endm

clearRegSubsUse macro regsubs, name
 irp reg, <&regsubs>
  clearRegSubsUse2 reg, name
 endm
endm

clearRegAddsUse2 macro reg, name
 getBigReg reg, %reglist, %Reglist
 set reg, %Reg
 set reg&name, <name&_not_in_use>
endm

clearRegAddsUse macro regadds, name
 irp reg, <&regadds>
  clearRegAddsUse2 reg, name
 endm
endm

setRegAlsoUse2 macro reguse, reg, Reg
 ifdif <reguse>, <Reg>
  ifdef reg&adds
   nameRegAdds % reg&adds, reg&_partly
  endif
 endif
endm

setRegAlsoUse macro regalso
 irp reg, <&regalso>
  getBigReg reg, %reglist, %Reglist
  setRegAlsoUse2 % &reg, reg, %Reg
 endm
endm

rFree macro reg, name
 checkStatusIs %status, <started>
 getBigReg reg, %reglist, %Reglist
 ifdef &reg
  checkRegUse %&reg, reg, name
 else
  outputError <reg has not been used with rName>
 endif
 ifdef &name
  checkNameUse %&name, name, %Reg
 else
  outputError <name has not been used with rName>
 endif
 set reg, %Reg
 set reg&name, <name&_not_in_use>
 set name, <name&_not_in_use>
 ifdef reg&subs
  clearRegSubsUse % reg&subs, PartOf&name
 endif
 ifdef reg&adds
  clearRegAddsUse % reg&adds, name&_partly
 endif
 ifdef reg&also
  setRegAlsoUse % reg&also
 endif
endm

checkStatusIsNot macro status, st
 ifidn <status>, <st>
  outputErrorOnAnyPass <rmacros is already st state>
 endif
endm

checkStatusIs macro status, st
 ifdif <status>, <st>
  outputErrorOnAnyPass <rmacros is not in st state>
 endif
endm

rStart macro
 ifdef status
  checkStatusIsNot %status, <started>
 endif
 status equ <started>
 ifdef STATUS
  .err
  %out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  %out !                                                 !
  %out ! rmacros must be used with full case sensitivity !
  %out !                                                 !
  %out !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  .err
 endif
 clearNamelists %reglist
 clearRegUses %reglist
 set whichlist, <A>
endm

clearNamelists2 macro reg
 set reg&namelist, <dmy>
endm

clearNamelists macro reglist
 irp reg, <reglist>
  clearNamelists2 reg
 endm
 namelistA equ <dmy>
 namelistB equ <dmy>
endm

clearNameUses6 macro name
 set name, <name&_not_in_use>
 ifidn <name>, <dmy>
  set namelistok, <true>
 endif
endm

clearNameUses5 macro namelist
 set namelistok, <false>
 irp name, <&namelist>
  clearNameUses6 name
 endm
 checkNameListOk %namelistok
endm

checkNameListOk macro namelistok
 ifidn <namelistok>, <false>
   outputErrorOnAnyPass < name list has overflowed - register usage names are too long in total >
   %out !! You must do one or more of the following:
   %out !!     - use shorter names
   %out !!     - less names
   %out !!     - partition your code more often using rStart/rEnd pairs
 endif
endm

clearNameUses4 macro reg, name
 ifdef reg&name
  set reg&name, <name&_not_in_use>
 endif
endm

clearNameUses3 macro reg, namelist
 irp name, <&namelist>
  clearNameUses4 reg, name
 endm
endm

clearNameUses2 macro reg
 clearNameUses3 reg, % reg&namelist
endm

clearNameUses macro reglist
 irp reg, <&reglist>
  clearNameUses2 reg
 endm
 clearNameUses5 %namelistA
 clearNameUses5 %namelistB
endm

clearRegUses macro reglist
 irp reg, <&reglist>
  getBigReg reg, %reglist, %Reglist
  set reg %Reg
 endm
endm

rEnd macro
 checkStatusIs %status, <started>
 status equ <ended>
 clearRegUses %reglist
 clearNameUses %reglist
endm

rInit macro
 outputError <rInit is not defined in this version of rmacros>
endm

rUse macro
 outputError <rUse is not defined in this version of rmacros>
endm

rCheck macro
 outputError <rCheck is not defined in this version of rmacros>
endm

ENDIF

; end of rmacros.inc
