home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / lib / psmacros.inc < prev    next >
Text File  |  1998-06-08  |  9KB  |  386 lines

  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/includes/rcs/psmacros.inc $
  13. ; $Revision: 1.12 $
  14. ; $Author: matt $
  15. ; $Date: 1994/12/06 14:32:19 $
  16. ;
  17. ; Useful macros.  Everyone should use these.
  18. ;
  19. ; $Log: psmacros.inc $
  20. ; Revision 1.12  1994/12/06  14:32:19  matt
  21. ; Made mprintf turn off if NMONO set
  22. ; Revision 1.11  1994/11/27  23:18:19  matt
  23. ; Made mprintf go away when debugging turned off
  24. ; Revision 1.10  1994/03/25  18:00:34  matt
  25. ; Added imulc of 6
  26. ; Revision 1.9  1994/02/10  18:00:58  matt
  27. ; Changed 'if DEBUG_ON' to 'ifndef NDEBUG'
  28. ; Revision 1.8  1993/11/22  23:47:06  matt
  29. ; debug macros were trashing eax
  30. ; Revision 1.7  1993/11/04  12:39:25  mike
  31. ; Modify imulc macro to support fast multiply by 36
  32. ; and multiply anything using imul, but give warning.
  33. ; Revision 1.6  1993/10/19  21:17:31  matt
  34. ; Added abs_eax macro
  35. ; Revision 1.5  1993/09/26  22:28:21  matt
  36. ; Removed extra register pushes in mprintf
  37. ; Make DEBUG_ON all uppercase since we seem to have case sensitivity on
  38. ; Revision 1.4  1993/09/26  19:22:30  matt
  39. ; Added imulc macro, to multiply a register by a constant.  It does not
  40. ; at this time support arbitrary constants, only 0,1,3,5,9, and powers of 2
  41. ; Revision 1.3  1993/09/13  11:50:57  matt
  42. ; Added 'b' & 'w', aliases for 'byte ptr' and 'word ptr'
  43. ; Revision 1.2  1993/09/03  19:00:03  matt
  44. ; Added breakpoint macros
  45. ; Revision 1.1  1993/08/24  12:51:52  matt
  46. ; Initial revision
  47. ;
  48. ;
  49.  
  50. ;Shortcuts for casting
  51.  
  52. w equ word ptr
  53. b equ byte ptr
  54.  
  55.  
  56. ;The macros @ArgCount() & @ArgRev() are from the file MACROS.INC, provided 
  57. ;with MASM.  I have included them here because MACROS.INC has bugs, so I 
  58. ;couldn't just include it.
  59.  
  60. ; Utility Macros - Version 1.0 - for Microsoft Macro Assembler 6.0
  61. ; (C) Copyright Microsoft Corporation, 1987,1988,1989,1990
  62.  
  63. ;* @ArgCount - Macro function returns the number of arguments in a
  64. ;* VARARG list.
  65. ;*
  66. ;* Params:  arglist - arguments to be counted
  67.  
  68. @ArgCount MACRO arglist:VARARG
  69.     LOCAL count
  70.     count = 0
  71.     FOR arg, <arglist>
  72.     count = count + 1
  73.     ENDM
  74.     EXITM %count
  75. ENDM
  76.  
  77. ;* @ArgRev - Macro function returns a reversed order version of a
  78. ;* VARARG list.
  79. ;*
  80. ;* Shows:   Operators           - <>         !        %
  81. ;*          String directive    - SUBSTR
  82. ;*          Predefined function - @SizeStr
  83. ;*
  84. ;* Params:  arglist - arguments to be reversed
  85.  
  86. @ArgRev MACRO arglist:vararg
  87.     LOCAL txt, arg
  88.     txt TEXTEQU <>
  89. %   FOR arg, <arglist>
  90.     txt CATSTR <arg>, <!,>, txt
  91.     ENDM
  92.  
  93.     txt SUBSTR  txt, 1, @SizeStr( %txt ) - 1
  94.     txt CATSTR  <!<>, txt, <!>>
  95.     EXITM txt
  96. ENDM
  97.  
  98. ;These macros are used for decalaring external vars and functions
  99.  
  100. ;this macro is used to declare several symbols of the same type
  101. ;usage is:  extdef  type,sym0,sym1,...
  102. extdef  macro   type,syms:vararg
  103.     for     sym,<syms>
  104.      externdef sym:type
  105.     endm
  106.     endm
  107.  
  108. ;this macro is used to generate ext<type> macros 
  109. extgen  macro   type,id
  110. ext&id  macro   syms:vararg
  111.     extdef  type,syms
  112.     endm
  113.     endm
  114.  
  115. ;macros for common types, such as word (extw), byte (extb), & near (extn)
  116.  
  117.     extgen  word,w
  118.     extgen  byte,b
  119.     extgen  dword,d
  120.     extgen  near,n
  121.  
  122.  
  123. ;compute the absolute value of eax.  afterwards, edx=sign (0 or -1)
  124. abs_eax macro
  125.     cdq
  126.     xor     eax,edx
  127.     sub     eax,edx
  128.     endm
  129.  
  130. ;PUSHM & POPM are used for multiple registers.  Note that POPM pops in the
  131. ;reverse order from PUSHM, so the list of regs shouls be the same for both.
  132. ;You can also define a constant which is a register list, and use it as the
  133. ;argument to both macros.
  134.  
  135. ;push multiple registers
  136. pushm   macro   args:vararg
  137.     local   arg
  138.     for     arg,<args>
  139.      push   arg
  140.     endm
  141.     endm
  142.  
  143. ;pop multiple registers
  144. popm    macro   args:vararg
  145.     local   arg
  146. %       for     arg,@ArgRev(args)
  147.      pop    arg
  148.     endm
  149.     endm
  150.  
  151. ;PUSHLONG pushes a long, zero extending the argument if necessary
  152. ;it trashes no registers
  153. pushlong        macro   arg
  154.     local   s
  155. s = TYPE arg
  156.     if      s EQ 0  ;constant, I think
  157.      push   arg
  158.     elseif  s LT 4
  159.      push   eax
  160.      movzx  eax,arg
  161.      xchg   eax,[esp]
  162.     else
  163.      push   arg
  164.     endif
  165.  
  166.     endm
  167.  
  168. ;PUSHML is pushm using pushlong
  169. pushml  macro   args:vararg
  170.     local   arg
  171.     for     arg,<args>
  172.      pushlong       arg
  173.     endm
  174.     endm
  175.  
  176.  
  177. ;DBSTR stores a string with occurances of \n converted to newlines
  178. ;this macro expects quotes around the string
  179. ;
  180. ;note the 'fudge' variable.  This fixes an odd problem with the way
  181. ;the string macros deal with backslashes - @InStr() treats them like
  182. ;any other character, but @SubStr() ignores them
  183. dbstr   macro   str
  184.  
  185.     local   pos,oldpos,len,fudge
  186.     oldpos = 2      ;skip initial quote
  187.     fudge = 0
  188.     len = @SizeStr(str)
  189.  
  190.     pos = @InStr(oldpos,str,<\n>)
  191.  
  192.     while   pos GE oldpos
  193.  
  194.      if     pos GT oldpos
  195.       %db   '&@SubStr(<&str>,&oldpos-&fudge,&pos-&oldpos)'
  196.      endif
  197.      db     10
  198.      oldpos = pos+2
  199.      fudge = fudge+1
  200.  
  201.      pos = @InStr(oldpos,<str>,<\n>)
  202.  
  203.     
  204.     endm
  205.     if      oldpos LT len
  206.     
  207. ;;;      %db    '&@SubStr(&str,&oldpos-&fudge,&len-&oldpos-1)'
  208.      %db    '&@SubStr(&str,&oldpos-&fudge,&len-&oldpos)'
  209.     endif
  210.  
  211. endm
  212.  
  213.  
  214. ;MPRINTF is a macro interface to the mprintf funcion.  It puts the format
  215. ;string in the code segment at the current location, pushes the args, and
  216. ;calls mprintf. If window is not specified, zero is assumed
  217. mprintf macro   window:=<0>,format:req,args:vararg
  218.     local   string,skip
  219.     ifndef  NDEBUG
  220.     ifndef  NMONO
  221.     extn    _mprintf_
  222.     jmp     skip
  223. string  label   byte
  224.     dbstr   format
  225.     db      0
  226. skip:
  227.     ifnb    <args>
  228. %        pushml @ArgRev(args)
  229.     endif
  230.     pushml  offset string,window
  231.     call    _mprintf_
  232.     add     esp,(@ArgCount(args)+2)*4       ;fix stack
  233.     endif
  234.     endif
  235.     endm
  236.  
  237.  
  238. ;MPRINTF_AT - version of mprintf with coordinates
  239. mprintf_at      macro   window:=<0>,row,col,format:req,args:vararg
  240.     local   string,skip
  241.     ifndef  NDEBUG
  242.     ifndef  NMONO
  243.     extn    _mprintf_at_
  244.     jmp     skip
  245. string  label   byte
  246.     dbstr   format
  247.     db      0
  248. skip:
  249.     ifnb    <args>
  250. %        pushml @ArgRev(args)
  251.     endif
  252.     pushml  offset string,col,row,window
  253.     call    _mprintf_at_
  254.     add     esp,(@ArgCount(args)+4)*4       ;fix stack
  255.     endif
  256.     endif
  257.     endm
  258.  
  259.  
  260. ;DEBUG calls mprintf with window 0, preserving all registers and flags
  261. ;is is conditionall assembled based on the DEBUG_ON flags
  262. debug   macro   format:req,args:vararg
  263.     ifndef  NDEBUG
  264.      pushf          ;save flags
  265.      push   eax     ;mprintf trashes eax
  266.      mprintf        ,format,args
  267.      pop    eax
  268.      popf
  269.     endif
  270.     endm
  271.  
  272. ;DEBUG_AT - version of debug with coordinates
  273. debug_at        macro   row,col,format:req,args:vararg
  274.     ifndef  NDEBUG
  275.      pushf          ;save flags
  276.      push   eax     ;mprintf trashes eax
  277.      mprintf_at ,row,col,format,args
  278.      pop    eax
  279.      popf
  280.     endif
  281.     endm
  282.  
  283. ;Debugging breakpoint macros
  284.  
  285. ;print a message, and do an int3 to pop into the debugger  
  286. debug_brk       macro   str
  287.     endm;added by KRB also. commented out this macro 
  288.     
  289. ;    ifndef  NDEBUG
  290. ;     debug  str
  291. ;     int    3
  292. ;    endif
  293. ;    endm
  294.  
  295. break_if        macro   cc,str
  296.     endm;Added by KRB - below code doesn't compile..
  297. ;    local   skip,yes_break
  298. ;    ifndef  NDEBUG
  299. ;     j&cc   yes_break
  300. ;     jmp    skip
  301. ;yes_break:       debug_brk str
  302. ;skip:
  303. ;    endif
  304. ;    endm
  305.  
  306. ;returns the bit number of the highest bit
  307. @HighBit        macro   n
  308.     local   t,c
  309.     if      n EQ 0
  310.      exitm  <-1>    ;error!
  311.     else
  312.      t = n
  313.      c = 0
  314.      while  t GT 1
  315.       t = t SHR 1
  316.       c = c+1
  317.      endm
  318.      exitm  <c>
  319.     endif
  320.     endm
  321.  
  322. ;returns the bit number of the lowest bit
  323. @LowBit macro   n
  324.     ;local  t,c
  325.     local   c
  326.     if      n EQ 0
  327.      exitm  <-1>    ;error!
  328.     else
  329.      t = n
  330.      c = 0
  331.      while  (t and 1) EQ 0
  332.       t = t SHR 1
  333.       c = c+1
  334.      endm
  335.      exitm  <c>
  336.     endif
  337.     endm
  338.  
  339.  
  340. ;"multiply" the given register by a constant, using whatever method is
  341. ;best for the given constant
  342. imulc   macro   reg,c
  343.     local   low,high
  344.  
  345.     if      c EQ 0
  346.      xor    reg,reg
  347.     elseif  c EQ 1
  348.     elseif  c EQ 3
  349.      lea    reg,[reg*2+reg]
  350.     elseif  c EQ 5
  351.      lea    reg,[reg*4+reg]
  352.     elseif  c EQ 6
  353.      lea    reg,[reg*2+reg] ;*3
  354.      shl    reg,1   ;*6
  355.     elseif  c EQ 9
  356.      lea    reg,[reg*8+reg]
  357.     elseif  c EQ 36
  358.      lea    reg,[reg*8+reg]
  359.      sal    reg,2
  360.     else
  361.      low = @LowBit(c)
  362.      high = @HighBit(c)
  363.      if     low EQ high
  364.       shl   reg,@LowBit(c)
  365.      else
  366.       imul  reg,c
  367.       echo  Warning: Using imul, to perform multiply by &c
  368.       ;; .err
  369.      endif
  370.     endif
  371.  
  372.     endm
  373.  
  374.