Metropoli BBS
VIEWER: callp.inc MODE: TEXT (ASCII)
callp macro a1:req,a2:vararg
  local siz,noargs,cnt,a3,a4,cnt2,axused,_esp,destroy_eax,type2

  destroy_eax = 0
;;  destroy_eax = 1
;;if you would like EAX to be destroyed for speed when
;;widening arguments then let destroy_eax = 1

  axused = 0  ;this is set to 1 if eax is trashed
  noargs = 0
  for a3,<a2>
    noargs = noargs+1
  endm
  cnt = noargs
  _esp = noargs*4
  repeat noargs
    cnt2=0
    for a4,<a2>
      cnt2 = cnt2+1
      if cnt2 eq cnt
        a3 textequ <a4>
      endif
    endm
    siz = type (a3)
    if axused eq 1
      ifidn a3,<eax>
        .err <EAX is destroyed!>
      endif   ;20
      ifidn a3,<ax>
        .err <EAX is destroyed!>
      endif
      ifidn a3,<al>
        .err <EAX is destroyed!>
      endif
      ifidn a3,<ah>
        .err <EAX is destroyed!>
      endif
    endif
    ifidn %siz,%0
      push a3
    elseifidn %siz,%1
      type2 = (opattr a3) and 16
      if (type2) eq 16   ;;is it a register?
        push dptr 0
        mov [esp],a3         
      else
        push dptr 0
        ife destroy_eax
          push ax
        else
          axused = 1
        endif
        mov al,a3
        ife destroy_eax
          mov [esp+2],al   ;;+2 cause AX is on the stack
          pop ax
        else
          mov [esp],al
        endif
      endif
    elseifidn %siz,%2
      push wptr 0
      push a3
    elseifidn %siz,%4
      push a3  ;line 44
    elseifidn %siz,%6   ;;FWORD  (pushed as a QWORD)
      push wptr 0
      push wptr (a3+4)
      push dptr a3
      _esp = _esp+4     ;;add 4 more bytes
    elseifidn %siz,%8   ;;REAL 8 (or QWORD)
      push dptr (a3+4)
      push dptr a3
      _esp = _esp+4     ;;add 4 more bytes
    elseifidn %siz,%10  ;;REAL 10 (or TWORD)
      push wptr (a3+8)
      push dptr (a3+4)
      push dptr a3
      _esp = _esp+6     ;;add 6 more bytes
    else
      % echo Warning: sizeof( a3 ) unknown.  Argument will be pushed 'as is'.
      push a3
    endif
    cnt = cnt - 1    ;;count backwards thru arguments for C calling convention
  endm
  call a1
  add esp,_esp
endm

[ RETURN TO DIRECTORY ]