home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / cruntime.inc < prev    next >
Text File  |  1998-06-17  |  21KB  |  783 lines

  1. ;***
  2. ;cruntime.inc - multi-model assembly macros for interfacing to HLLs
  3. ;
  4. ;       Copyright (c) 1988-1997, Microsoft Corporation.  All rights reserved.
  5. ;
  6. ;Purpose:
  7. ;       This file defines the current memory model being used.
  8. ;
  9. ;*******************************************************************************
  10.  
  11. ;==============================================================================
  12. ;
  13. ;Use the following defines to control processor/segment model
  14. ;
  15. ;   -DI86               8086/8088 processor
  16. ;   -DI286              80286 processor
  17. ;   -DI386              80386 processor with 32-bit code/data segment
  18. ;
  19. ;   -Dmem_S             Small memory model   (near code, near data)
  20. ;   -Dmem_M             Medium memory model  (far code, near data)
  21. ;   -Dmem_C             Compact memory model (near code, fat data)
  22. ;   -Dmem_L             Large memory model   (far code, far data)
  23. ;
  24. ;   -DSS_NEQ_DGROUP     SS and DS point to different segments
  25. ;
  26. ;   default is -DI86 -Dmem_S
  27. ;
  28. ;==============================================================================
  29. ;
  30. ;The following variables are defined by this file:
  31. ;   cpu                         86, 286, or 386
  32. ;   sizeC                       code distance; 1 = far code, 0 = near code
  33. ;   sizeD                       data distance; 1 = far data, 0 = near data
  34. ;   mmodel                      english name of the memory model, i.e. "Medium"
  35. ;   ISIZE, LSIZE, NSIZE         size of ints, longs, shorts
  36. ;   FLTSIZE, DBLSIZE, LDBLSIZE  size of float, double, long double
  37. ;   NPSIZE, FPSIZE              size of near/far pointers
  38. ;   CPSIZE, DPSIZE              size of code/data pointers
  39. ;   ISHIFT, LSHIFT              bits to shift to convert byte to int/long
  40. ;
  41. ;The following macros allow easy writing of combined 16/32 bit code:
  42. ;
  43. ; 16/32 bit registers:
  44. ;   rax, rbx, rcx, rdx,         expand to native registers (rax = eax or ax)
  45. ;   rsi, rdi, rsp, rbp
  46. ; 16/32 bit register instructions:
  47. ;   JRCXZ                       jump when rcx is zero
  48. ;   CBI                         convert byte to int (al to rax)
  49. ;   CAXDX                       convert rax to rax:rdx
  50. ;   ZXAL, ZXBL, ZXCL, ZXDL      zero extend al,bl,cl,dl to rax,rbx,rcx,rdx
  51. ; Pointer instructions:
  52. ;   LPDS, LPES                  load data pointer with ES or DS
  53. ;   PDS, PES                    segment overrides when pointer loaded as above
  54. ;   PCS, PSS                    segment override to get at code/stack segment
  55. ;   LFPDS, LFPES                load far pointer with ES or DS
  56. ;   FPDS, FPES                  segment overrides when pointer loaded as above
  57. ;   CPTR                        data type of code pointer
  58. ;   CPDIST                      distance of code (near/far)
  59. ;   DNPTR, DFPTR                define near/far pointer
  60. ;   DCPTR, DDPTR                define code/data pointer
  61. ;   DCPTR?, DDPTR?              define uninitialized code/data pointer
  62. ;   CPWORD, DPWORD              data type of code or data pointer
  63. ; Numeric type instructions:
  64. ;   IWORD, LWORD, SWORD         data type of int, long, short
  65. ;   DINT, DLONG, DSHORT         define int, long, short
  66. ;   DFLOAT, DDOUBLE, DLDOUBLE   define float, double, long double
  67. ; Offsets:
  68. ;   codeoffset, dataoffset      offsets from code and data segments
  69. ; API calls:
  70. ;   APIDIST                     distance of API calls (near/far)
  71. ;   APIEXT ApiName              extrn declaration for an API function
  72. ;
  73. ;The following utility macros are provided:
  74. ;   codeseg                     define/declare code segment
  75. ;   error <msg>                 stop assembly with message
  76. ;   display <msg>               display a message, unless QUIET defined
  77. ;   savelist [<reg> ...]        init list of regs to be save by 'proc uses'
  78. ;   _if cond <instruction>      assemble instruction only if cond is TRUE
  79. ;   _ife cond <instruction>     assemble instruction only if cond is FALSE
  80. ;   _ifd symbol <instruction>   assemble instruction only if symbol defined
  81. ;   _ifnd symbol <instruction>  assemble instruction only if symbol not defined
  82. ;
  83. ;   lab  LabelName              assembles to "LabelName:" If DEBUG is defined
  84. ;                               LabelName is made public
  85. ;
  86. ;   JS* (ex. JSE,JSZ,JSB ...)   assemble to "je short","jz short","jb short"
  87. ;
  88. ;   Cmacro look alikes
  89. ;   static* Name, InitialValue, Repeat   defines a static variable of type *
  90. ;   global* Name, InitialValue, Repeat   defines a global variable of type *
  91. ;   label*  Name, {PUBLIC,PASCAL,C}      defines a label of type *
  92. ;
  93. ;   PUSH16  SegmentReg          pushes 16 bits in a use32 segment
  94. ;   JMPFAR16  label             will do a far 16:16 jmp from a use32 segment
  95. ;
  96. ;==============================================================================
  97.  
  98. ; error <msg>   -    Output message and generate error
  99.  
  100. error   MACRO   msg
  101. if2                     ;; only on pass 2 can we generate errors
  102.         %out    **********************************************************
  103.         %out    *** E r r o r  --  msg
  104.         %out    **********************************************************
  105.         .err
  106. endif
  107.         ENDM
  108.  
  109. ; display msg   -    Output message unless QUIET defined
  110.  
  111. display MACRO   msg
  112. ifndef QUIET            ;; only when quiet flag not set
  113. if1                     ;; and on pass 1, then display message
  114.         %out msg
  115. endif
  116. endif
  117.         ENDM
  118.  
  119. ; One line conditionals:
  120. ;   here we create the capability of writing code lines like
  121. ;
  122. ; _if sizeD   <push ds>   as opposed to    if sizeD
  123. ;                                              push  ds
  124. ;                                          endif
  125.  
  126. _if     MACRO   cond,text
  127.     if  cond
  128.         text
  129.     endif
  130.         ENDM
  131.  
  132. _ife    MACRO   cond,text
  133.     ife cond
  134.         text
  135.     endif
  136.         ENDM
  137.  
  138. _ifd    MACRO   cond,text
  139.     ifdef   cond
  140.         text
  141.     endif
  142.         ENDM
  143.  
  144. _ifnd   MACRO   cond,text
  145.     ifndef  cond
  146.         text
  147.     endif
  148.         ENDM
  149.  
  150. ; set windows flag to 0
  151.  
  152.         ?WIN    equ     0       ; disable windows-specific code
  153.  
  154. ; check for _MT, requires 286 or greater processor
  155.  
  156. ifdef _MT
  157. ifndef I386
  158. ifndef I286
  159. ; _MT implies 286 processor
  160. display <Multi-thread specified - assuming 80286 processor>
  161. I286 equ <>
  162. endif
  163. endif
  164. endif
  165.  
  166. ; Process memory-model arguments
  167.  
  168. ifdef  mem_M
  169.         ; Medium model
  170.         sizeC   equ     1
  171.         sizeD   equ     0
  172.         mmodel  equ     <Medium>
  173. elseifdef  mem_C
  174.         ; Compact model
  175.         sizeC   equ     0
  176.         sizeD   equ     1
  177.         mmodel  equ     <Compact>
  178. elseifdef  mem_L
  179.         ; Large model
  180.         sizeC   equ     1
  181.         sizeD   equ     1
  182.         mmodel  equ     <Large>
  183. else
  184.         ; Small model - default
  185.         sizeC   equ     0
  186.         sizeD   equ     0
  187.         mmodel  equ     <Small>
  188. endif
  189.  
  190. ; Process processor arguments
  191.  
  192. ifdef   _WIN32
  193.         display <Processor:             486/586>
  194.         cpu equ 586
  195.         .586
  196. elseifdef       _POSIX_
  197.         display <Processor:             486/586>
  198.         cpu equ 586
  199.         .586
  200. elseifdef   I286
  201.         display <Processor:             80286>
  202.         cpu equ 286
  203.         .286
  204. elseifdef   I386
  205.         display <Processor:             80386>
  206.         cpu equ 386
  207.         .386
  208. else
  209.         display <Processor:             8086/8088>
  210.         cpu equ 86
  211.         .8086
  212. endif
  213.  
  214. ;  386 32-bit checking.  Currently we are only expecting small model
  215. ;  32 bit segments, so we make a few checks to be sure nothing is
  216. ;  incorrectly being defined.
  217.  
  218. ifdef I386
  219.     if sizeC or sizeD
  220.         error <Must use Small memory model for 386 version.>
  221.     endif
  222.  
  223.     ifdef _LOAD_DGROUP
  224.         error <No loading DGROUP in 386 version.>
  225.     endif
  226.  
  227.     ifdef SS_NEQ_DGROUP
  228.         error <SS always equals DGROUP in 386 version.>
  229.     endif
  230. endif
  231.  
  232. ;  Set memory model
  233.  
  234. %       display <Memory model:          mmodel>
  235. %       .model  mmodel, C
  236.  
  237. ;
  238. ; *** Temporary Workaround ***
  239. ; Currently, MASM will not recognize the 'FLAT' keyword unless it previously
  240. ; appears in an 'assume' statement.  Presumably, when the '.model FLAT' feature
  241. ; is implemented, this will go away.  [Use 'gs:' since we never use that
  242. ; segment register.
  243. ;
  244.  
  245. ifdef   I386
  246.         ; ensure that MASM recognizes 'FLAT'
  247.         assume  gs:FLAT
  248. endif
  249.  
  250.  
  251. ; Define registers:
  252. ; Instead of using the "word" registers directly, we will use a set of
  253. ; text equates.  This will allow you to use the native word size instead of
  254. ; hard coded to 16 bit words.  We also have some instruction equates for
  255. ; instruction with the register type hard coded in.
  256.  
  257. ifdef I386
  258.  
  259.     rax equ <eax>
  260.     rbx equ <ebx>
  261.     rcx equ <ecx>
  262.     rdx equ <edx>
  263.     rdi equ <edi>
  264.     rsi equ <esi>
  265.     rbp equ <ebp>
  266.     rsp equ <esp>
  267.  
  268.     JRCXZ equ <jecxz>
  269.     CBI   equ <movsx eax, al>    ; convert byte to int (al to rax)
  270.     CAXDX equ <cdq>              ; convert rax to rdx:rax
  271.     ZXAL  equ <movzx eax, al>    ; zero extend al
  272.     ZXBL  equ <movzx ebx, bl>    ; zero extend bl
  273.     ZXCL  equ <movzx ecx, cl>    ; zero extend cl
  274.     ZXDL  equ <movzx edx, dl>    ; zero extend dl
  275.  
  276. else
  277.  
  278.     rax equ <ax>
  279.     rbx equ <bx>
  280.     rcx equ <cx>
  281.     rdx equ <dx>
  282.     rdi equ <di>
  283.     rsi equ <si>
  284.     rbp equ <bp>
  285.     rsp equ <sp>
  286.  
  287.     JRCXZ equ <jcxz>
  288.     CBI   equ <cbw>              ; convert byte to int (al to rax)
  289.     CAXDX equ <cwd>              ; convert rax to rdx:rax
  290.     ZXAL  equ <xor ah, ah>       ; zero extend al
  291.     ZXBL  equ <xor bh, bh>       ; zero extend bl
  292.     ZXCL  equ <xor ch, ch>       ; zero extend cl
  293.     ZXDL  equ <xor dh, dh>       ; zero extend dl
  294.  
  295. endif
  296.  
  297. ; The following equates deal with the differences in near versus
  298. ; far data pointers, and segment overrides.
  299. ;
  300. ; Use LPES and PES when loading a default size pointer -- it loads
  301. ; a 16-bit pointer register in 286 Small/Medium model,
  302. ; a 16-bit pointer register and 16-bit segment register in 8086/286
  303. ; Compact/Large model, and a 32-bit pointer register in 386 mode.
  304. ;
  305. ; Use LFPES and FPES when loading an always far pointer -- it loads a
  306. ; 16-bit pointer register and 16-bit segment register in 8086/286,
  307. ; all models; a 32-bit pointer register in 386 mode.
  308.  
  309. if sizeD
  310.     LPES equ <les>
  311.     LPDS equ <lds>
  312.     PDS  equ <ds:>
  313.     PES  equ <es:>
  314. else
  315.     LPES equ <mov>
  316.     LPDS equ <mov>
  317.     PDS  equ <>
  318.     PES  equ <>
  319. endif
  320.  
  321. ifdef I386
  322.     LFPES equ <mov>
  323.     LFPDS equ <mov>
  324.     FPES equ <>
  325.     FPDS equ <>
  326. else
  327.     LFPES equ <les>
  328.     LFPDS equ <lds>
  329.     FPES equ <es:>
  330.     FPDS equ <ds:>
  331. endif
  332.  
  333. if sizeC or @WordSize eq 2
  334.     PCS  equ <cs:>              ; large code model or non-386
  335. else
  336.  IF 1   ;*** TEMP 16/32 TESTBED ***
  337.     PCS  equ <cs:>
  338.  ELSE
  339.     PCS  equ <>                 ; 386 small code model
  340.  ENDIF  ;*** END TEMP CODE
  341. endif
  342.  
  343. ifdef SS_NEQ_DGROUP
  344.     PSS   equ <ss:>             ; SS != DS
  345. else
  346.     PSS   equ <>                ; SS == DS
  347. endif
  348.  
  349. ; Define offset macros:
  350. ;   The 32-bit segments will not have 'groups'
  351.  
  352. ifdef I386
  353.     codeoffset  equ <offset FLAT:>
  354.     dataoffset  equ <offset FLAT:>
  355. else
  356.     codeoffset  equ <offset @code:>
  357.     dataoffset  equ <offset DGROUP:>
  358. endif
  359.  
  360. ; The next set of equates deals with the size of SHORTS, INTS, LONGS, and
  361. ; pointers in the 16 and 32 bit versions.
  362.  
  363. ifdef I386       ;--- 32 bit segment ---
  364.  
  365.     ; parameters and locals
  366.     IWORD   equ <dword>
  367.     LWORD   equ <dword>
  368.  
  369.     ; static storage
  370.     DINT    equ <dd>
  371.     DLONG   equ <dd>
  372.     DSHORT  equ <dw>
  373.  
  374.     ; sizes for fixing SP, stepping through tables, etc.
  375.     ISIZE   equ 4
  376.     LSIZE   equ 4
  377.     SSIZE   equ 2
  378.     NPSIZE  equ 4
  379.     FPSIZE  equ 4
  380.  
  381.     ; bit shift count to convert byte cnt/ptr to int/long cnt/ptr
  382.     ISHIFT  equ 2               ; byte-to-int shift count
  383.     LSHIFT  equ 2               ; byte-to-long shift count
  384.  
  385.     ; sizes dependent upon memory model.  dq -vs- df is not yet clear
  386.     DNPTR equ <dd>              ; near pointer
  387.     DFPTR equ <dd>              ; far pointer
  388.  
  389.     DCPTR   equ <dd offset FLAT:>; 32 bit offset only
  390.     DCPTR?  equ <dd>            ; No seg override for uninitialized values
  391.     CPSIZE  equ 4
  392.     CPDIST  equ <near>          ; code pointers are near
  393.     CPTR    equ <near ptr>
  394.  
  395.     DDPTR   equ <dd offset FLAT:>
  396.     DDPTR?  equ <dd>
  397.     DPSIZE  equ 4
  398.  
  399.     CPWORD  equ <dword>         ; code pointers are dwords
  400.     DPWORD  equ <dword>         ; data pointers are dwords
  401.  
  402.     APIDIST equ <near>          ; all API calls are NEAR in the 32 bit model
  403.  
  404. ; macro to declare API functions
  405. EXTAPI  macro   apiname
  406.         extrn pascal apiname:near
  407. endm
  408.  
  409. else    ;--- 16-bit segment ---
  410.  
  411.     ; parameters and locals
  412.     IWORD   equ <word>
  413.     LWORD   equ <dword>
  414.  
  415.     ; static storage
  416.     DINT    equ <dw>
  417.     DLONG   equ <dd>
  418.     DSHORT  equ <dw>
  419.  
  420.     ; sizes for fixing SP, stepping through tables, etc
  421.     ISIZE   equ 2
  422.     LSIZE   equ 4
  423.     SSIZE   equ 2
  424.     NPSIZE  equ 2
  425.     FPSIZE  equ 4
  426.  
  427.     ; bit shift count to convert byte cnt/ptr to int/long cnt/ptr
  428.     ISHIFT  equ 1               ; byte-to-int shift count
  429.     LSHIFT  equ 2               ; byte-to-long shift count
  430.  
  431.     ; sizes dependent upon memory model
  432.     DNPTR equ <dw>              ; near pointer
  433.     DFPTR equ <dd>              ; far pointer
  434.  
  435.     if sizeC
  436.         DCPTR   equ <dd>       ; 16 bit segment and 16 bit offset
  437.         DCPTR?  equ <dd>
  438.         CPSIZE  equ 4
  439.         CPDIST  equ <far>      ; code pointers are far
  440.         CPTR    equ <far ptr>
  441.         CPWORD  equ <dword>    ; code pointers are dwords
  442.     else
  443.         DCPTR   equ <dw>       ; 16 bit offset only
  444.         DCPTR?  equ <dw>
  445.         CPSIZE  equ 2
  446.         CPDIST  equ <near>     ; code pointers are near
  447.         CPTR    equ <near ptr>
  448.         CPWORD  equ <word>     ; code pointers are words
  449.     endif
  450.  
  451.     if sizeD
  452.         DDPTR   equ <dd>
  453.         DDPTR?  equ <dd>
  454.         DPSIZE  equ 4
  455.         DPWORD  equ <dword>    ; data pointers are dwords
  456.     else
  457.         DDPTR   equ <dw>
  458.         DDPTR?  equ <dw>
  459.         DPSIZE  equ 2
  460.         DPWORD  equ <word>     ; data pointers are words
  461.     endif
  462.  
  463.     APIDIST equ <far>           ; API calls are FAR in 16 bit model
  464.  
  465. ; macro to declare API functions
  466. EXTAPI  macro   apiname
  467.         extrn pascal apiname:far
  468. endm
  469.  
  470. endif   ; --- 16/32 segment ---
  471.  
  472. ; Float/double definitions
  473. ; (currently the same for 16- and 32-bit segments)
  474.  
  475. FLTSIZE  equ    4       ; float
  476. DBLSIZE  equ    8       ; double
  477. LDBLSIZE equ    10      ; long double
  478.  
  479. DFLOAT   equ    <dd>
  480. DDOUBLE  equ    <dq>
  481. DLDOUBLE equ    <dt>
  482.  
  483. ;
  484. ; savelist - Generate a list of regs to be saved by the proc 'uses' option.
  485. ;
  486. ; Input:
  487. ;       reg1, reg2, reg3, reg4 = registers to be saved across function
  488. ; Output:
  489. ;       reglist = text string of registers that can be passed to the 'uses'
  490. ;       option on the 'proc' command.
  491. ;
  492.  
  493. savelist  MACRO   reg1, reg2, reg3, reg4
  494.         local   ws, listsize
  495.         ws      catstr  < >             ; whitespace char
  496.  
  497.         IFNDEF  I386
  498.          rbx equ <>                     ; 8086/286 don't save rbx
  499.         ENDIF
  500.  
  501.         IFNB        <reg4>
  502.          reglist     catstr  reg1, ws, reg2, ws, reg3, ws, reg4
  503.         ELSEIFNB    <reg3>
  504.          reglist     catstr  reg1, ws, reg2, ws, reg3, ws
  505.         ELSEIFNB    <reg2>
  506.          reglist     catstr  reg1, ws, reg2, ws,       ws
  507.         ELSEIFNB    <reg1>
  508.          reglist     catstr  reg1, ws,       ws,       ws
  509.         ELSE
  510.          reglist     catstr  <>
  511.         ENDIF
  512.  
  513.         listsize sizestr reglist        ; size of register list
  514.  
  515.         IF      listsize LE 3           ; if list is only the 3 ws chars...
  516.          reglist catstr  <>
  517.         ENDIF
  518.  
  519.         IFNDEF  I386
  520.          rbx equ <bx>                   ; restore rbx
  521.         ENDIF
  522.  
  523.         ENDM    ; savelist
  524.  
  525. ;
  526. ; codeseg - Define/declare the standard code segment. Maps to the proper
  527. ; form of the .code directive.
  528. ;
  529. ; Input:
  530. ;
  531. ; Output:
  532. ;       .code _TEXT     ; for large code models
  533. ;       .code           ; for small code models
  534. ;       assume  cs:FLAT ; for 386
  535. ;       assume  ds:FLAT ; for 386
  536. ;       assume  es:FLAT ; for 386
  537. ;       assume  ss:FLAT ; for 386
  538. ;
  539.  
  540. codeseg MACRO
  541.  
  542. if      sizeC
  543.         .code _TEXT
  544. else
  545.         .code
  546. endif
  547.  
  548. ifdef   I386
  549.         assume  ds:FLAT
  550.         assume  es:FLAT
  551.         assume  ss:FLAT
  552. endif
  553.  
  554.         ENDM
  555.  
  556. ;*========
  557. ;*
  558. ;*  Debug lab macro
  559. ;*
  560. ;*========
  561.  
  562. lab     macro name
  563. ifdef   DEBUG
  564.     public  pascal name     ;; define label public for Symdeb
  565. endif
  566. name:
  567.         endm
  568.  
  569.  
  570. ;*========
  571. ;*
  572. ;*  Conditional jump short macros
  573. ;*
  574. ;*========
  575.  
  576.  
  577.         irp     x,<Z,NZ,E,NE,S,NS,C,NC,P,NP,PE,PO,A,AE,B,BE,NB,G,GE,L,LE>
  578. JS&x    equ   <j&x short>
  579.         endm
  580.  
  581.  
  582. ;*========
  583. ;*
  584. ;*  Global data definition macros
  585. ;*
  586. ;*  Usage:
  587. ;*      globalI   Name, InitialValue, Repeat
  588. ;*
  589. ;*========
  590.  
  591.  
  592. MakeGlobal  macro   suffix, DataType        ;; makes all of the global* macros
  593.  
  594. global&suffix  macro   name, data, rep
  595. public  name
  596. ifb     <rep>
  597.     _repeat = 1
  598. else
  599.     _repeat = (rep)
  600. endif
  601.  
  602. name    &DataType  _repeat dup( data )
  603.         endm
  604.  
  605.         endm
  606.  
  607.  
  608.     MakeGlobal  T, dt                   ; globalT
  609.     MakeGlobal  Q, dq                   ; globalQ
  610.     MakeGlobal  D, dd                   ; globalD
  611.     MakeGlobal  W, dw                   ; globalW
  612.     MakeGlobal  B, db                   ; globalB
  613.  
  614. %   MakeGlobal  I, <DINT>               ; globalI
  615.  
  616. %   MakeGlobal  DP, <DDPTR>             ; globalDP
  617. %   MakeGlobal  CP, <DCPTR>             ; globalCP
  618. %   MakeGlobal  FP, <DFPTR>             ; globalFP
  619. %   MakeGlobal  NP, <DNPTR>             ; globalNP
  620.  
  621.  
  622.  
  623. ;*========
  624. ;*
  625. ;*  Static data definition macros
  626. ;*
  627. ;*  Usage:
  628. ;*      staticI   Name, InitialValue, Repeat
  629. ;*
  630. ;*========
  631.  
  632.  
  633. MakeStatic  macro   suffix, DataType        ;; makes all of the static* macros
  634.  
  635. static&suffix  macro   name, data, rep
  636.  
  637. ifdef  DEBUG
  638.     public  pascal name                     ;; make statics public if DEBUG
  639. endif
  640.  
  641. ifb     <rep>
  642.     _repeat = 1
  643. else
  644.     _repeat = (rep)
  645. endif
  646.  
  647. name    &DataType  _repeat dup( data )
  648.         endm
  649.  
  650.         endm
  651.  
  652.  
  653.     MakeStatic  T, dt                   ; staticT
  654.     MakeStatic  Q, dq                   ; staticQ
  655.     MakeStatic  D, dd                   ; staticD
  656.     MakeStatic  W, dw                   ; staticW
  657.     MakeStatic  B, db                   ; staticB
  658.  
  659. %   MakeStatic  I, <DINT>               ; staticI
  660.  
  661. %   MakeStatic  DP, <DDPTR>             ; staticDP
  662. %   MakeStatic  CP, <DCPTR>             ; staticCP
  663. %   MakeStatic  FP, <DFPTR>             ; staticFP
  664. %   MakeStatic  NP, <DNPTR>             ; staticNP
  665.  
  666. ;*========
  667. ;*
  668. ;*  Label definition macros
  669. ;*
  670. ;*========
  671. ;*
  672. ;*  Label definition macros
  673. ;*
  674. ;*  Usage:
  675. ;*      labelI   Name, {PUBLIC, PASCAL, C}
  676. ;*
  677. ;*========
  678.  
  679. __MakePublic    macro   name, option    ;; decides if a label should be
  680. ifidni  <option>, <PUBLIC>              ;; made public
  681.     public  name
  682. elseifidni  <option>, <PASCAL>
  683.     public  pascal name
  684. elseifidni  <option>, <C>
  685.     public  C name
  686. elseifb  <option>
  687.     ifdef  DEBUG
  688.         public  pascal name     ;; make public if DEBUG
  689.     endif
  690. endif
  691.                 endm
  692.  
  693.  
  694. MakeLabel   macro suffix, LabelType     ;; makes all of the label* macros
  695.  
  696. %@CatStr(<label>,<suffix>)      macro   name, option
  697.         __MakePublic    <name>,<option>
  698. name    label   &LabelType
  699.         endm
  700.  
  701.         endm
  702.  
  703.  
  704.         MakeLabel   T, tbyte    ; make labelT
  705.         MakeLabel   Q, qword    ; make labelQ
  706.         MakeLabel   D, dword    ; make labelD
  707.         MakeLabel   W, word     ; make labelW
  708.         MakeLabel   B, byte     ; make labelB
  709.  
  710.         MakeLabel   P, proc     ; make labelP
  711.         MakeLabel   FP, far     ; make labelFP
  712.         MakeLabel   NP, near    ; make labelNP
  713.  
  714. %       MakeLabel   I, IWORD    ; make labelI
  715.  
  716.  
  717. labelDP macro   name, option                ;; labelDP
  718.         __MakePublic    <name>,<option>
  719. ifdef  I386
  720.     if sizeD
  721.         name    label   fword
  722.     else
  723.         name    label   dword
  724.     endif
  725. else    ;not I386
  726.     if sizeD
  727.         name    label   dword
  728.     else
  729.         name    label   word
  730.     endif
  731. endif   ;not I386
  732.         endm
  733.  
  734. labelCP macro   name, option                ;; labelCP
  735.         __MakePublic    <name>,<option>
  736. ifdef  I386
  737.     if sizeC
  738.         name    label   fword
  739.     else
  740.         name    label   dword
  741.     endif
  742. else    ;not I386
  743.     if sizeC
  744.         name    label   dword
  745.     else
  746.         name    label   word
  747.     endif
  748. endif   ;not I386
  749.         endm
  750.  
  751.  
  752. ;*
  753. ;*  PUSH16 SegReg   - pushes 16 bits in a use32 segment
  754. ;*
  755.  
  756. PUSH16  macro   SegReg
  757.  
  758. ifdef I386
  759.         nop
  760.         db      66h         ; operand size over-ride
  761. endif   ; I386
  762.  
  763.         push    SegReg
  764.         endm
  765.  
  766.  
  767. ;*
  768. ;*  JMPFAR16  label - jmps far from a use32 to a use16 segment
  769. ;*
  770.  
  771. JMPFAR16 macro  label
  772.  
  773. ifndef I386
  774.         error  <JMPFAR16 can only be used in a use32 code segment>
  775. endif   ;I386
  776.  
  777.         nop
  778.         db      66h         ;; operand size over-ride
  779.         db      0eah        ;; jmp far immediate op code
  780.         dw      offset label
  781.         dw      seg label
  782.         endm
  783.