home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c221 / 5.ddi / MWHC.005 / I3 < prev    next >
Encoding:
Text File  |  1992-12-09  |  12.1 KB  |  526 lines

  1. ;
  2. ; (C) Copyright 1987-1992;    MetaWare Incorporated
  3. ;
  4. ifdef mach386
  5.     include chip386.inc
  6. else
  7.     ifdef machx86
  8.         include chip86.inc
  9.     else
  10.         %out1 >>>> Target machine not specified for macros file.
  11.         %out1 >>>> You must define either "mach386" or "machx86"
  12.         %out1 >>>> on the assembler command line.
  13.         .err
  14.     endif
  15. endif
  16.  
  17. ifndef GOC
  18.     ifndef LOC
  19.     %out1 >>>> Target compiler type not specified for macros file.
  20.     %out1 >>>> You must specify either "LOC" for a LOC compiler,
  21.     %out1 >>>> or "GOC" for a GOC compiler
  22.     .err
  23.     endif
  24. endif
  25.  
  26. ; Known Anomolies: Currently won't support automatic variables ie [bp-x]
  27. ; unless expilitly coded
  28.  
  29. ; Set pointer size.
  30. PUSH_COUNT = 0      ; currently you have not pushed anything.
  31. NO_BP_V = 0
  32.  
  33. ifdef   Large_data
  34. Ptr_size    equ   Word_size * 2 ; pass 8 bytes at a time for a 6-byte ptr.
  35. Ptr_reg         equ     es      ; Use es.
  36. Stack_reg       equ     ss      ; Use ss.
  37. else
  38. Ptr_size        equ     Word_size
  39. Ptr_reg         equ     ds      ; Can use ds, since = es.
  40. Stack_reg       equ     ds      ; Can use ds, since = ss.
  41. endif
  42.  
  43. ifdef   Small_code
  44.   Pbase   =     Word_size   ; Location of first parameter.
  45.   Routine_size= Word_size   ; link + offset.
  46.  
  47.   return  macro Pop_bytes
  48.     ifb   <Pop_bytes>
  49.         db 0c3h ; ret  near
  50.     else
  51.         db      0c2h  ; ret near N bytes
  52.         dw      Pop_bytes
  53.     endif
  54.   endm
  55.   extrnf  macro   name
  56.   extrn   name:near
  57.   endm
  58. else
  59.   Pbase   =       Word_size * 2 ; Location of first parameter.
  60.   Routine_size=   Word_size * 2      ; Link + offset + segment.
  61.  
  62.   return  macro   Pop_bytes
  63.     ifb   <Pop_bytes>
  64.         db 0cbh ;ret far
  65.     else
  66.         db      0cah  ; ret far N bytes
  67.         dw      Pop_bytes
  68.     endif
  69.   endm
  70.   extrnf  macro   name
  71.   extrn   name:far
  72.   endm
  73. endif
  74.  
  75. PROLOG_PUSH macro p_reg
  76.       ifidn <ebx>,<p_reg>
  77.         PUSH_EBX = 1
  78.       else
  79.         ifidn <edi>,<p_reg>
  80.           PUSH_EDI = 1
  81.         else
  82.           ifidn <esi>,<p_reg>
  83.             PUSH_ESI = 1
  84.           else
  85.             ifidn <es>,<p_reg>
  86.               PUSH_ES = 1
  87.             else
  88.               ifidn <ds>,<p_reg>
  89.                 PUSH_DS = 1
  90.               else
  91.                 ifidn <ebp>,<p_reg>
  92.                   if NO_BP_V eq 1
  93.                     PUSH_EBP = 1
  94.                   else
  95.         mov ax,ERROR ; ebp already used in prolog.  Option is only valid with:
  96.         mov ax,ERROR ;  prolog  no_bp [,<regs, can include ebp>]
  97.                   endif
  98.                 endif
  99.               endif
  100.             endif
  101.           endif
  102.         endif
  103.       endif
  104.       endm
  105.  
  106. PUSH_IT macro reg
  107.         if NO_BP_V eq 1
  108.            PUSH_COUNT =  Word_size + PUSH_COUNT
  109.         endif
  110.         push    reg
  111.         endm
  112.  
  113. POP_IT macro reg
  114.         if NO_BP_V eq 1
  115.            PUSH_COUNT =  PUSH_COUNT - Word_size
  116.         endif
  117.         pop     reg
  118.         endm
  119.  
  120. PUSH_REGS macro
  121.      if Word_size eq 2
  122.         if PUSH_EBX eq 1
  123.           PUSH_IT bx
  124.           endif
  125.         if PUSH_EDI eq 1
  126.           PUSH_IT    di
  127.           endif
  128.         if PUSH_ESI eq 1
  129.           PUSH_IT    si
  130.           endif
  131.  
  132.         if PUSH_EBP eq 1
  133.           if NO_BP_V eq 1
  134.             PUSH_IT    bp
  135.           else
  136.         mov ax,ERROR ;pushing ebp invalid without prolog no_bp [,<regs>]
  137.             endif
  138.           endif
  139.      else
  140.         if PUSH_EBX eq 1
  141.           PUSH_IT   ebx
  142.           endif
  143.         if PUSH_EDI eq 1
  144.           PUSH_IT    edi
  145.           endif
  146.         if PUSH_ESI eq 1
  147.           PUSH_IT    esi
  148.           endif
  149.         if PUSH_EBP eq 1
  150.           if NO_BP_V eq 1
  151.             PUSH_IT    ebp
  152.           else
  153.         mov ax,ERROR ;pushing ebp invalid without prolog no_bp [,<regs>]
  154.             endif
  155.           endif
  156.         endif
  157.      if PUSH_DS eq 1
  158.         PUSH_IT    ds
  159.         endif
  160.      if PUSH_ES eq 1
  161.         PUSH_IT    es
  162.         endif
  163.      endm
  164.  
  165. prolog  macro   r1,r2,r3,r4,r5,r6,r7,r8,r9
  166.         L_DATA_V = 0
  167.         PUSH_EBX = 0
  168.         PUSH_EDI = 0
  169.         PUSH_ESI = 0
  170.         PUSH_DS = 0
  171.         PUSH_ES = 0
  172.         PUSH_EBP = 0
  173.  
  174.         align 4
  175.         ifidn   <>,<r1>
  176.         push    ebp
  177.         mov     ebp,esp
  178.         NO_BP_V  = 0
  179.         PUSH_ESI = 1
  180.         PUSH_EDI = 1
  181.         PUSH_EBX = 1
  182.  ifdef   Large_data ; Save DS whether or not 1 DS, in case we modify it.
  183.         PUSH_DS = 1
  184.  endif
  185.         else
  186.           ifdif   <no_bp>,<r1>
  187.         push    ebp
  188.         mov     ebp,esp
  189.             NO_BP_V  = 0
  190.           else
  191.             NO_BP_V = 1
  192.           endif
  193.           irp     Reg,<r1,r2,r3,r4,r5,r6,r7,r8,r9>
  194.             ifnb    <Reg>
  195.               ifdif   <l_data>,<reg>
  196.                 ifdif   <no_bp>,<reg>
  197.                   ifdef Large_data
  198.                       PROLOG_PUSH  <Reg>
  199.                   else
  200.                     if L_DATA_V eq 0
  201.                       PROLOG_PUSH  <Reg>
  202.                     else
  203.                     endif
  204.                   endif
  205.                 endif
  206.               else
  207.                 L_DATA_V = 1
  208.               endif
  209.             endif
  210.           endm
  211.         endif
  212.         PUSH_REGS
  213.         endm
  214.  
  215. POP_REGS macro
  216.         if PUSH_ES eq 1
  217.         POP_IT     es
  218.         endif
  219.         if PUSH_DS eq 1
  220.         POP_IT     ds
  221.         endif
  222.         if Word_size eq 2
  223.           if PUSH_EBP eq 1
  224.             POP_IT     bp
  225.             endif
  226.           if PUSH_ESI eq 1
  227.             POP_IT     si
  228.             endif
  229.           if PUSH_EDI eq 1
  230.             POP_IT     di
  231.             endif
  232.           if PUSH_EBX eq 1
  233.             POP_IT     bx
  234.             endif
  235.         else
  236.           if PUSH_EBP eq 1
  237.             POP_IT     ebp
  238.             endif
  239.           if PUSH_ESI eq 1
  240.             POP_IT     esi
  241.             endif
  242.           if PUSH_EDI eq 1
  243.             POP_IT     edi
  244.             endif
  245.           if PUSH_EBX eq 1
  246.             POP_IT     ebx
  247.             endif
  248.           endif
  249.         endm
  250.  
  251. epilog  macro  r1
  252.       POP_REGS
  253.       if PUSH_COUNT eq 0
  254.       else
  255.         mov ax,ERROR ;YOU HAVE AN UNBALANCED STACK, FIX it or adjust PUSH_COUNT
  256.         int  PUSH_COUNT  ; The number  after int is how many bytes you are off
  257.       endif
  258.       if NO_BP_V eq 0
  259.         pop     ebp
  260.       endif
  261.       ifidn   <r1>,<>
  262.         return
  263.       else
  264.         return <r1>
  265.       endif
  266.     endm
  267.  
  268. ; We would have preferred a procbeg and procend macro, but
  269. ; the "proc" directive can't go inside a macro -- yet another
  270. ; of the many bugs in the flaky Microsoft assembler.
  271. publab  macro   procname
  272.         public  _mw&procname
  273. _mw&procname:
  274.         endm
  275. cseg    macro   segname,status
  276.         name    &segname
  277. ifb     <status>
  278. _MW&segname     segment dword 'CODE'
  279. else
  280. _MW&segname     segment dword 'CODE' public
  281. endif
  282.         assume  cs:_MW&segname
  283. ifdef   Small_code
  284. CGROUP  group   _MW&segname
  285.         assume  cs:CGROUP
  286. endif
  287.         endm
  288. endcseg macro   segname
  289. _MW&segname     ends
  290.         endm
  291. pubnames macro  names
  292.         irp     name,<names>
  293. ifdef   USING_MASM
  294.         public  _mw&&name
  295. else
  296.         public  _mw&name
  297. endif
  298.         endm
  299.         endm
  300. pubname macro   name
  301.         public  _mw&name
  302.         endm
  303. def     macro   x,y,z
  304. _mw&x   y       z
  305.         endm
  306. defequ  macro   x,y,z
  307. _mw&x   y       z
  308. x       equ     _mw&x
  309.         endm
  310. extequ  macro   x,type
  311.         extrn   _mw&x:type
  312. x       equ     _mw&x
  313.         endm
  314. ext     macro   x,type
  315.         extrn   _mw&x:type
  316.         endm
  317. ; Macros for parameter set-up that take care of small vs. large code
  318. ; and to some extent small vs. large data.
  319. ; Calling sequence:
  320. ; parms   <<N1,T1>,<N2,T2>,...>
  321. ; where Ni are the names and Ti the types.
  322. ; This expands into
  323. ;       Ni equ T1 ptr offset[bp]
  324. ; where offset starts at the appropriate value for a procedure
  325. ; (assuming BP has been pushed, and taking into account small vs lg code)
  326. ; and is incremented as follows:
  327. ;       if Ti = "ptr" then increment by Ptr_size
  328. ;       otherwise increment by 2.
  329. ; For example:
  330. ;       parms   <<Src,word>,<Dest,ptr>,<Cnt,word>>
  331. ; generates
  332. ;       Src equ word ptr 6[bp]
  333. ;       Dest equ dword ptr 8[bp]
  334. ;       Cnt equ word ptr 12[bp]
  335. ; assuming parms start at 6.
  336.  
  337. parm    macro   P,Type
  338.         local   Offset
  339. Offset  equ     Poff+0  ; +0 avoids alias; forces pass1 computation of expn.
  340. ifidn   <Type>,<ptr>    ; Type = "ptr"?
  341.   ifdef Small_data
  342.      if NO_BP_V eq 0
  343. P       equ     dword ptr Offset[ebp+Word_size]
  344.      else
  345. P       equ     dword ptr Offset[esp+PUSH_COUNT]
  346.      endif
  347.   else
  348.      if NO_BP_V eq 0
  349. P       equ     qword ptr Offset[ebp+Word_size]
  350.      else
  351. P       equ     qword ptr Offset[esp+PUSH_COUNT]
  352.      endif
  353.   endif
  354. Poff    =       Poff + Ptr_size
  355. else
  356. ifidn   <Type>,<routine>        ; Type = "routine"?
  357.   ifdef Small_code
  358.      if NO_BP_V eq 0
  359. P       equ     word ptr Offset[ebp+Word_size]
  360.      else
  361. P       equ     word ptr Offset[esp+PUSH_COUNT]
  362.      endif
  363.   else
  364.      if NO_BP_V eq 0
  365. P       equ     dword ptr Offset[ebp+Word_size]
  366.      else
  367. P       equ     dword ptr Offset[esp+PUSH_COUNT]
  368.      endif
  369.   endif
  370. Poff    =       Poff + Routine_size - Word_size ; DOES NOT skip link.
  371. else
  372.      if NO_BP_V eq 0
  373. P       equ     Type ptr Offset[ebp+Word_size]
  374.      else
  375. P       equ     Type ptr Offset[esp+PUSH_COUNT]
  376.      endif
  377. Poff    =       Poff + Word_size
  378. endif
  379. endif
  380.         endm
  381.  
  382. parmreg macro   P,Type,Offset
  383. ifidn   <Type>,<ptr>    ; Type = "ptr"?
  384.      if NO_BP_V eq 0
  385.         P       equ     dword ptr Offset[ebp+Word_size]
  386.      else
  387.         P       equ     dword ptr Offset[esp+PUSH_COUNT]
  388.     endif
  389. else
  390. ifidn   <Type>,<routine>        ; Type = "routine"?
  391.      if NO_BP_V eq 0
  392.         P       equ     word ptr Offset[ebp+Word_size]
  393.      else
  394.         P       equ     word ptr Offset[esp+PUSH_COUNT]
  395.      endif
  396. else
  397.      if NO_BP_V eq 0
  398.         P       equ     Type ptr Offset[ebp+Word_size]
  399.      else
  400.         P       equ     Type ptr Offset[esp+PUSH_COUNT]
  401.      endif
  402. endif
  403. endif
  404.         endm
  405.  
  406. parms   macro   Parmlist
  407.         Poff    =       Pbase   ; ret addr + pushed bp.
  408.         pdummy  =  2
  409.         irp     P,<Parmlist>
  410.      ;   ife     pdummy
  411.      ;     int 255
  412.      ;     parmreg P,-4
  413.      ;   else
  414.      ;     int 254
  415.      ;     ife     pdummy-1
  416.      ;       int 253
  417.      ;       parmreg P,-8
  418.      ;     else
  419.      ;       int 252
  420.             parm    P
  421.      ;     endif
  422.      ;   endif
  423. pdummy  =       pdummy+1
  424.         endm
  425.         endm
  426.  
  427. parm386 macro   parmlist
  428.         parms   <parmlist>
  429.         endm
  430. parm86  macro   parmlist
  431.         endm
  432.  
  433. ; Load a pointer.
  434. ifdef   Small_data
  435. loadptr macro   Seginstr,Ireg,Operand
  436.         mov     Ireg,Operand
  437.         endm
  438. else
  439. loadptr macro   Seginstr,Ireg,Operand
  440.         Seginstr Ireg,dword ptr Operand
  441.         endm
  442. endif
  443.  
  444. ; Load a formal routine parameter.
  445. ifdef   Small_code
  446. loadrout macro  Segreg,Ireg,Operand
  447.         mov     Ireg,Operand
  448.         PUSH_IT    cs
  449.         POP_IT     Segreg
  450.         endm
  451. else
  452. loadrout macro  Segreg,Ireg,Operand
  453.         L&Segreg Ireg,dword ptr Operand
  454.         endm
  455. endif
  456.  
  457. ; Call a procedure.
  458. ifdef   Small_code
  459. pcall   macro   procname
  460. ifdef   USING_MASM
  461.         call    procname        ; MASM 5.1 BUG!!
  462.                                 ; MASM doesn't put out proper LEdata for the call below.
  463. else
  464.         call    CGROUP:(near ptr procname)
  465. endif
  466.         endm
  467. else
  468. pcall   macro   procname
  469.         call    far ptr procname
  470.         endm
  471. endif
  472.  
  473. MWINT21 macro
  474.         call _mwint21
  475.         endm
  476.  
  477.         extrnf  _mwint21
  478.  
  479. ; For GOC, the constructor entries consist of a 4-byte order field, a
  480. ; 4-byte function address, and a 4-byte reserved field.  For LOC, only
  481. ; the address is used.
  482. addinit macro i1
  483.  
  484. _MWIFC  segment public word 'DATA'
  485. _MWIFC  ends
  486. _MWIMC  segment public word 'DATA'
  487.  
  488.     ifdef GOC
  489.     dd    128
  490.     endif
  491.  
  492.     dd    i1
  493.  
  494.     ifdef GOC
  495.     dd    0
  496.     endif
  497.  
  498. _MWIMC  ends
  499. _MWILC  segment public word 'DATA'
  500. _MWILC  ends
  501.  
  502.     endm
  503.  
  504. adddest macro i1
  505.  
  506. _MWDFC  segment public word 'DATA'
  507. _MWDFC  ends
  508. _MWDMC  segment public word 'DATA'
  509.  
  510.     ifdef GOC
  511.     dd    128
  512.     endif
  513.  
  514.     dd    i1
  515.  
  516.     ifdef GOC
  517.     dd    0
  518.     endif
  519.  
  520. _MWDMC  ends
  521. _MWDLC  segment public word 'DATA'
  522. _MWDLC  ends
  523.  
  524.     endm
  525.  
  526.