| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224 |
- ;****************************************************************************
- ;*
- ;* ========================================================================
- ;*
- ;* The contents of this file are subject to the SciTech MGL Public
- ;* License Version 1.0 (the "License"); you may not use this file
- ;* except in compliance with the License. You may obtain a copy of
- ;* the License at http://www.scitechsoft.com/mgl-license.txt
- ;*
- ;* Software distributed under the License is distributed on an
- ;* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- ;* implied. See the License for the specific language governing
- ;* rights and limitations under the License.
- ;*
- ;* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
- ;*
- ;* The Initial Developer of the Original Code is SciTech Software, Inc.
- ;* All Rights Reserved.
- ;*
- ;* ========================================================================
- ;*
- ;* Language: NetWide Assembler (NASM) or Turbo Assembler (TASM)
- ;* Environment: Any Intel Environment
- ;*
- ;* Description: Macros to provide memory model independant assembly language
- ;* module for C programming. Supports the large and flat memory
- ;* models.
- ;*
- ;* The defines that you should use when assembling modules that
- ;* use this macro package are:
- ;*
- ;* __LARGE__ Assemble for 16-bit large model
- ;* __FLAT__ Assemble for 32-bit FLAT memory model
- ;* __NOU__ No underscore for all external C labels
- ;* __NOU_VAR__ No underscore for global variables only
- ;*
- ;* The default settings are for 16-bit large memory model with
- ;* leading underscores for symbol names.
- ;*
- ;* The main intent of the macro file is to enable programmers
- ;* to write _one_ set of source that can be assembled to run
- ;* in either 16 bit real and protected modes or 32 bit
- ;* protected mode without the need to riddle the code with
- ;* 'if flatmodel' style conditional assembly (it is still there
- ;* but nicely hidden by a macro layer that enhances the
- ;* readability and understandability of the resulting code).
- ;*
- ;****************************************************************************
- ; Include the appropriate version in here depending on the assembler. NASM
- ; appears to always try and parse code, even if it is in a non-compiling
- ; block of a ifdef expression, and hence crashes if we include the TASM
- ; macro package in the same header file. Hence we split the macros up into
- ; two separate header files.
- ifdef __NASM_MAJOR__
- ;============================================================================
- ; Macro package when compiling with NASM.
- ;============================================================================
- ; Turn off underscores for globals if disabled for all externals
- %ifdef __NOU__
- %define __NOU_VAR__
- %endif
- ; Define the __WINDOWS__ symbol if we are compiling for any Windows
- ; environment
- %ifdef __WINDOWS16__
- %define __WINDOWS__ 1
- %endif
- %ifdef __WINDOWS32__
- %define __WINDOWS__ 1
- %define __WINDOWS32_386__ 1
- %endif
- ; Macros for accessing 'generic' registers
- %ifdef __FLAT__
- %idefine _ax eax
- %idefine _bx ebx
- %idefine _cx ecx
- %idefine _dx edx
- %idefine _si esi
- %idefine _di edi
- %idefine _bp ebp
- %idefine _sp esp
- %idefine _es
- %idefine UCHAR BYTE ; Size of a character
- %idefine USHORT WORD ; Size of a short
- %idefine UINT DWORD ; Size of an integer
- %idefine ULONG DWORD ; Size of a long
- %idefine BOOL DWORD ; Size of a boolean
- %idefine DPTR DWORD ; Size of a data pointer
- %idefine FDPTR FWORD ; Size of a far data pointer
- %idefine NDPTR DWORD ; Size of a near data pointer
- %idefine CPTR DWORD ; Size of a code pointer
- %idefine FCPTR FWORD ; Size of a far code pointer
- %idefine NCPTR DWORD ; Size of a near code pointer
- %idefine FPTR NEAR ; Distance for function pointers
- %idefine DUINT dd ; Declare a integer variable
- %idefine intsize 4
- %idefine flatmodel 1
- %else
- %idefine _ax ax
- %idefine _bx bx
- %idefine _cx cx
- %idefine _dx dx
- %idefine _si si
- %idefine _di di
- %idefine _bp bp
- %idefine _sp sp
- %idefine _es es:
- %idefine UCHAR BYTE ; Size of a character
- %idefine USHORT WORD ; Size of a short
- %idefine UINT WORD ; Size of an integer
- %idefine ULONG DWORD ; Size of a long
- %idefine BOOL WORD ; Size of a boolean
- %idefine DPTR DWORD ; Size of a data pointer
- %idefine FDPTR DWORD ; Size of a far data pointer
- %idefine NDPTR WORD ; Size of a near data pointer
- %idefine CPTR DWORD ; Size of a code pointer
- %idefine FCPTR DWORD ; Size of a far code pointer
- %idefine NCPTR WORD ; Size of a near code pointer
- %idefine FPTR FAR ; Distance for function pointers
- %idefine DUINT dw ; Declare a integer variable
- %idefine intsize 2
- %endif
- %idefine invert ~
- %idefine offset
- %idefine use_nasm
- ; Convert all jumps to near jumps, since NASM does not so this automatically
- %idefine jo jo near
- %idefine jno jno near
- %idefine jz jz near
- %idefine jnz jnz near
- %idefine je je near
- %idefine jne jne near
- %idefine jb jb near
- %idefine jbe jbe near
- %idefine ja ja near
- %idefine jae jae near
- %idefine jl jl near
- %idefine jle jle near
- %idefine jg jg near
- %idefine jge jge near
- %idefine jc jc near
- %idefine jnc jnc near
- %idefine js js near
- %idefine jns jns near
- %ifdef DOUBLE
- %idefine REAL QWORD
- %idefine DREAL dq
- %else
- %idefine REAL DWORD
- %idefine DREAL dd
- %endif
- ; Boolean truth values (same as those in debug.h)
- %idefine False 0
- %idefine True 1
- %idefine No 0
- %idefine Yes 1
- %idefine Yes 1
- ; Macro to be invoked at the start of all modules to set up segments for
- ; later use. Does nothing for NASM.
- %imacro header 1
- %endmacro
- ; Macro to begin a data segment
- %imacro begdataseg 1
- %ifdef __GNUC__
- segment .data public class=DATA use32 flat
- %else
- %ifdef flatmodel
- segment _DATA public align=4 class=DATA use32 flat
- %else
- segment _DATA public align=4 class=DATA use16
- %endif
- %endif
- %endmacro
- ; Macro to end a data segment
- %imacro enddataseg 1
- %endmacro
- ; Macro to begin a code segment
- %imacro begcodeseg 1
- %ifdef __GNUC__
- segment .text public class=CODE use32 flat
- %else
- %ifdef flatmodel
- segment _TEXT public align=16 class=CODE use32 flat
- %else
- segment %1_TEXT public align=16 class=CODE use16
- %endif
- %endif
- %endmacro
- ; Macro to begin a near code segment
- %imacro begcodeseg_near 0
- %ifdef __GNUC__
- segment .text public class=CODE use32 flat
- %else
- %ifdef flatmodel
- segment _TEXT public align=16 class=CODE use32 flat
- %else
- segment _TEXT public align=16 class=CODE use16
- %endif
- %endif
- %endmacro
- ; Macro to end a code segment
- %imacro endcodeseg 1
- %endmacro
- ; Macro to end a near code segment
- %imacro endcodeseg_near 0
- %endmacro
- ; Macro for an extern C symbol. If the C compiler requires leading
- ; underscores, then the underscores are added to the symbol names, otherwise
- ; they are left off. The symbol name is referenced in the assembler code
- ; using the non-underscored symbol name.
- %imacro cextern 2
- %ifdef __NOU_VAR__
- extern %1
- %else
- extern _%1
- %define %1 _%1
- %endif
- %endmacro
- %imacro cexternfunc 2
- %ifdef __NOU__
- extern %1
- %else
- extern _%1
- %define %1 _%1
- %endif
- %endmacro
- ; Macro for a public C symbol. If the C compiler requires leading
- ; underscores, then the underscores are added to the symbol names, otherwise
- ; they are left off. The symbol name is referenced in the assembler code
- ; using the non-underscored symbol name.
- %imacro cpublic 1
- %ifdef __NOU_VAR__
- global %1
- %1:
- %else
- global _%1
- _%1:
- %define %1 _%1
- %endif
- %endmacro
- ; Macro for an global C symbol. If the C compiler requires leading
- ; underscores, then the underscores are added to the symbol names, otherwise
- ; they are left off. The symbol name is referenced in the assembler code
- ; using the non-underscored symbol name.
- %imacro cglobal 1
- %ifdef __NOU_VAR__
- global %1
- %else
- global _%1
- %define %1 _%1
- %endif
- %endmacro
- ; Macro for an global C function symbol. If the C compiler requires leading
- ; underscores, then the underscores are added to the symbol names, otherwise
- ; they are left off. The symbol name is referenced in the assembler code
- ; using the non-underscored symbol name.
- %imacro cglobalfunc 1
- %ifdef __NOU__
- global %1
- %else
- global _%1
- %define %1 _%1
- %endif
- %endmacro
- ; Macro to start a C callable function. This will be a far function for
- ; 16-bit code, and a near function for 32-bit code.
- %imacro cprocstatic 1
- %push cproc
- %1:
- %ifdef flatmodel
- %stacksize flat
- %define ret retn
- %else
- %stacksize large
- %define ret retf
- %endif
- %assign %$localsize 0
- %endmacro
- %imacro cprocstart 1
- %push cproc
- cglobalfunc %1
- %1:
- %ifdef flatmodel
- %stacksize flat
- %define ret retn
- %else
- %stacksize large
- %define ret retf
- %endif
- %assign %$localsize 0
- %endmacro
- ; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
- ; calling conventions are always _far _pascal for 16 bit DLL's, we actually
- ; rename this routine with an extra underscore with 'C' calling conventions
- ; and a small DLL stub will be provided by the high level code to call the
- ; assembler routine.
- %imacro cprocstartdll16 1
- %ifdef __WINDOWS16__
- cprocstart _%1
- %else
- cprocstart %1
- %endif
- %endmacro
- ; Macro to start a C callable near function.
- %imacro cprocnear 1
- %push cproc
- cglobalfunc %1
- %1:
- %define ret retn
- %ifdef flatmodel
- %stacksize flat
- %else
- %stacksize small
- %endif
- %assign %$localsize 0
- %endmacro
- ; Macro to start a C callable far function.
- %imacro cprocfar 1
- %push cproc
- cglobalfunc %1
- %1:
- %define ret retf
- %ifdef flatmodel
- %stacksize flat
- %else
- %stacksize large
- %endif
- %assign %$localsize 0
- %endmacro
- ; Macro to end a C function
- %imacro cprocend 0
- %pop
- %endmacro
- ; Macros for entering and exiting C callable functions. Note that we must
- ; always save and restore the SI and DI registers for C functions, and for
- ; 32 bit C functions we also need to save and restore EBX and clear the
- ; direction flag.
- %imacro enter_c 0
- push _bp
- mov _bp,_sp
- %ifnidn %$localsize,0
- sub _sp,%$localsize
- %endif
- %ifdef flatmodel
- push ebx
- %endif
- push _si
- push _di
- %endmacro
- %imacro leave_c 0
- pop _di
- pop _si
- %ifdef flatmodel
- pop ebx
- cld
- %endif
- %ifnidn %$localsize,0
- mov _sp,_bp
- %endif
- pop _bp
- %endmacro
- %imacro use_ebx 0
- %ifdef flatmodel
- push ebx
- %endif
- %endmacro
- %imacro unuse_ebx 0
- %ifdef flatmodel
- pop ebx
- %endif
- %endmacro
- ; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
- ; be used in assembly routines. This evaluates to nothing in the flat memory
- ; model, but is saves and restores DS in the large memory model.
- %imacro use_ds 0
- %ifndef flatmodel
- push ds
- %endif
- %endmacro
- %imacro unuse_ds 0
- %ifndef flatmodel
- pop ds
- %endif
- %endmacro
- %imacro use_es 0
- %ifndef flatmodel
- push es
- %endif
- %endmacro
- %imacro unuse_es 0
- %ifndef flatmodel
- pop es
- %endif
- %endmacro
- ; Macros for loading the address of a data pointer into a segment and
- ; index register pair. The %imacro explicitly loads DS or ES in the 16 bit
- ; memory model, or it simply loads the offset into the register in the flat
- ; memory model since DS and ES always point to all addressable memory. You
- ; must use the correct _REG (ie: _BX) %imacros for documentation purposes.
- %imacro _lds 2
- %ifdef flatmodel
- mov %1,%2
- %else
- lds %1,%2
- %endif
- %endmacro
- %imacro _les 2
- %ifdef flatmodel
- mov %1,%2
- %else
- les %1,%2
- %endif
- %endmacro
- ; Macros for adding and subtracting a value from registers. Two value are
- ; provided, one for 16 bit modes and another for 32 bit modes (the extended
- ; register is used in 32 bit modes).
- %imacro _add 3
- %ifdef flatmodel
- add e%1, %3
- %else
- add %1, %2
- %endif
- %endmacro
- %imacro _sub 3
- %ifdef flatmodel
- sub e%1, %3
- %else
- sub %1, %2
- %endif
- %endmacro
- ; Macro to clear the high order word for the 32 bit extended registers.
- ; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
- ; value, and will evaluate to nothing in 16 bit modes.
- %imacro clrhi 1
- %ifdef flatmodel
- movzx e%1,%1
- %endif
- %endmacro
- %imacro sgnhi 1
- %ifdef flatmodel
- movsx e%1,%1
- %endif
- %endmacro
- ; Macro to load an extended register with an integer value in either mode
- %imacro loadint 2
- %ifdef flatmodel
- mov e%1,%2
- %else
- xor e%1,e%1
- mov %1,%2
- %endif
- %endmacro
- ; Macros to load and store integer values with string instructions
- %imacro LODSINT 0
- %ifdef flatmodel
- lodsd
- %else
- lodsw
- %endif
- %endmacro
- %imacro STOSINT 0
- %ifdef flatmodel
- stosd
- %else
- stosw
- %endif
- %endmacro
- ; Macros to provide resb, resw, resd compatibility with NASM
- %imacro dclb 1
- times %1 db 0
- %endmacro
- %imacro dclw 1
- times %1 dw 0
- %endmacro
- %imacro dcld 1
- times %1 dd 0
- %endmacro
- ; macros to declare assembler function stubs for function structures
- %imacro BEGIN_STUBS_DEF 2
- begdataseg _STUBS
- %ifdef __NOU_VAR__
- extern %1
- %define STUBS_START %1
- %else
- extern _%1
- %define STUBS_START _%1
- %endif
- enddataseg _STUBS
- begcodeseg _STUBS
- %assign off %2
- %endmacro
- %imacro DECLARE_STUB 1
- %ifdef __NOU__
- global %1
- %1:
- %else
- global _%1
- _%1:
- %endif
- jmp [DWORD STUBS_START+off]
- %assign off off+4
- %endmacro
- %imacro DECLARE_STDCALL 2
- %ifdef STDCALL_MANGLE
- global _%1@%2
- _%1@%2:
- %else
- %ifdef __GNUC__
- global _%1
- _%1:
- %else
- global %1
- %1:
- %endif
- %endif
- jmp [DWORD STUBS_START+off]
- %assign off off+4
- %endmacro
- %imacro END_STUBS_DEF 0
- endcodeseg _STUBS
- %endmacro
- ; macros to declare assembler import stubs for binary loadable drivers
- %imacro BEGIN_IMPORTS_DEF 1
- BEGIN_STUBS_DEF %1,4
- %endmacro
- %imacro DECLARE_IMP 1
- DECLARE_STUB %1
- %endmacro
- %imacro END_IMPORTS_DEF 0
- END_STUBS_DEF
- %endmacro
- else ; __NASM_MAJOR__
- ;============================================================================
- ; Macro package when compiling with TASM.
- ;============================================================================
- ; Turn off underscores for globals if disabled for all externals
- ifdef __NOU__
- __NOU_VAR__ = 1
- endif
- ; Define the __WINDOWS__ symbol if we are compiling for any Windows
- ; environment
- ifdef __WINDOWS16__
- __WINDOWS__ = 1
- endif
- ifdef __WINDOWS32__
- __WINDOWS__ = 1
- __WINDOWS32_386__ = 1
- endif
- ifdef __WIN386__
- __WINDOWS__ = 1
- __WINDOWS32_386__ = 1
- endif
- ifdef __VXD__
- __WINDOWS__ = 1
- __WINDOWS32_386__ = 1
- MASM
- .386
- NO_SEGMENTS = 1
- include vmm.inc ; IGNORE DEPEND
- include vsegment.inc ; IGNORE DEPEND
- IDEAL
- endif
- ; Macros for accessing 'generic' registers
- ifdef __FLAT__
- _ax EQU eax ; EAX is used for accumulator
- _bx EQU ebx ; EBX is used for accumulator
- _cx EQU ecx ; ECX is used for looping
- _dx EQU edx ; EDX is used for data register
- _si EQU esi ; ESI is the source index register
- _di EQU edi ; EDI is the destination index register
- _bp EQU ebp ; EBP is used for base pointer register
- _sp EQU esp ; ESP is used for stack pointer register
- _es EQU ; ES and DS are the same in 32 bit PM
- typedef UCHAR BYTE ; Size of a character
- typedef USHORT WORD ; Size of a short
- typedef UINT DWORD ; Size of an integer
- typedef ULONG DWORD ; Size of a long
- typedef BOOL DWORD ; Size of a boolean
- typedef DPTR DWORD ; Size of a data pointer
- typedef FDPTR FWORD ; Size of a far data pointer
- typedef NDPTR DWORD ; Size of a near data pointer
- typedef CPTR DWORD ; Size of a code pointer
- typedef FCPTR FWORD ; Size of a far code pointer
- typedef NCPTR DWORD ; Size of a near code pointer
- typedef DUINT DWORD ; Declare a integer variable
- FPTR EQU NEAR ; Distance for function pointers
- intsize = 4 ; Size of an integer
- flatmodel = 1 ; This is a flat memory model
- P386 ; Turn on 386 code generation
- MODEL FLAT ; Set up for 32 bit simplified FLAT model
- else
- _ax EQU ax ; AX is used for accumulator
- _bx EQU bx ; BX is used for accumulator
- _cx EQU cx ; CX is used for looping
- _dx EQU dx ; DX is used for data register
- _si EQU si ; SI is the source index register
- _di EQU di ; DI is the destination index register
- _bp EQU bp ; BP is used for base pointer register
- _sp EQU sp ; SP is used for stack pointer register
- _es EQU es: ; ES is used for segment override
- typedef UCHAR BYTE ; Size of a character
- typedef USHORT WORD ; Size of a short
- typedef UINT WORD ; Size of an integer
- typedef ULONG DWORD ; Size of a long
- typedef BOOL WORD ; Size of a boolean
- typedef DPTR DWORD ; Size of a data pointer
- typedef FDPTR DWORD ; Size of a far data pointer
- typedef NDPTR WORD ; Size of a near data pointer
- typedef CPTR DWORD ; Size of a code pointer
- typedef FCPTR DWORD ; Size of a far code pointer
- typedef NCPTR WORD ; Size of a near code pointer
- typedef DUINT WORD ; Declare a integer variable
- FPTR EQU FAR ; Distance for function pointers
- intsize = 2 ; Size of an integer
- P386 ; Turn on 386 code generation
- endif
- invert EQU not
- ; Provide a typedef for real floating point numbers
- ifdef DOUBLE
- typedef REAL QWORD
- typedef DREAL QWORD
- else
- typedef REAL DWORD
- typedef DREAL DWORD
- endif
- ; Macros to access the floating point stack registers to convert them
- ; from NASM style to TASM style
- st0 EQU st(0)
- st1 EQU st(1)
- st2 EQU st(2)
- st3 EQU st(3)
- st4 EQU st(4)
- st5 EQU st(5)
- st6 EQU st(6)
- st7 EQU st(7)
- st8 EQU st(8)
- ; Boolean truth values (same as those in debug.h)
- ifndef __VXD__
- False = 0
- True = 1
- No = 0
- Yes = 1
- Yes = 1
- endif
- ; Macros for the _DATA data segment. This segment contains initialised data.
- MACRO begdataseg name
- ifdef __VXD__
- MASM
- VXD_LOCKED_DATA_SEG
- IDEAL
- else
- ifdef flatmodel
- DATASEG
- else
- SEGMENT _DATA DWORD PUBLIC USE16 'DATA'
- endif
- endif
- ENDM
- MACRO enddataseg name
- ifdef __VXD__
- MASM
- VXD_LOCKED_DATA_ENDS
- IDEAL
- else
- ifndef flatmodel
- ENDS _DATA
- endif
- endif
- ENDM
- ; Macro for the main code segment.
- MACRO begcodeseg name
- ifdef __VXD__
- MASM
- VXD_LOCKED_CODE_SEG
- IDEAL
- else
- ifdef flatmodel
- CODESEG
- ASSUME CS:FLAT,DS:FLAT,SS:FLAT
- else
- SEGMENT &name&_TEXT PARA PUBLIC USE16 'CODE'
- ASSUME CS:&name&_TEXT,DS:_DATA
- endif
- endif
- ENDM
- ; Macro for a near code segment
- MACRO begcodeseg_near
- ifdef flatmodel
- CODESEG
- ASSUME CS:FLAT,DS:FLAT,SS:FLAT
- else
- SEGMENT _TEXT PARA PUBLIC USE16 'CODE'
- ASSUME CS:_TEXT,DS:_DATA
- endif
- ENDM
- MACRO endcodeseg name
- ifdef __VXD__
- MASM
- VXD_LOCKED_CODE_ENDS
- IDEAL
- else
- ifndef flatmodel
- ENDS &name&_TEXT
- endif
- endif
- ENDM
- MACRO endcodeseg_near
- ifndef flatmodel
- ENDS _TEXT
- endif
- ENDM
- ; Macro to be invoked at the start of all modules to set up segments for
- ; later use.
- MACRO header name
- begdataseg name
- enddataseg name
- ENDM
- ; Macro for an extern C symbol. If the C compiler requires leading
- ; underscores, then the underscores are added to the symbol names, otherwise
- ; they are left off. The symbol name is referenced in the assembler code
- ; using the non-underscored symbol name.
- MACRO cextern name,size
- ifdef __NOU_VAR__
- EXTRN name:size
- else
- EXTRN _&name&:size
- name EQU _&name&
- endif
- ENDM
- MACRO cexternfunc name,size
- ifdef __NOU__
- EXTRN name:size
- else
- EXTRN _&name&:size
- name EQU _&name&
- endif
- ENDM
- MACRO stdexternfunc name,args,size
- ifdef STDCALL_MANGLE
- EXTRN _&name&@&num_args&:size
- name EQU _&name&@&num_args
- else
- EXTRN name:size
- endif
- ENDM
- ; Macro for a public C symbol. If the C compiler requires leading
- ; underscores, then the underscores are added to the symbol names, otherwise
- ; they are left off. The symbol name is referenced in the assembler code
- ; using the non-underscored symbol name.
- MACRO cpublic name
- ifdef __NOU_VAR__
- name:
- PUBLIC name
- else
- _&name&:
- PUBLIC _&name&
- name EQU _&name&
- endif
- ENDM
- ; Macro for an global C symbol. If the C compiler requires leading
- ; underscores, then the underscores are added to the symbol names, otherwise
- ; they are left off. The symbol name is referenced in the assembler code
- ; using the non-underscored symbol name.
- MACRO cglobal name
- ifdef __NOU_VAR__
- PUBLIC name
- else
- PUBLIC _&name&
- name EQU _&name&
- endif
- ENDM
- ; Macro for an global C function symbol. If the C compiler requires leading
- ; underscores, then the underscores are added to the symbol names, otherwise
- ; they are left off. The symbol name is referenced in the assembler code
- ; using the non-underscored symbol name.
- MACRO cglobalfunc name
- ifdef __NOU__
- PUBLIC name
- else
- PUBLIC _&name&
- name EQU _&name&
- endif
- ENDM
- ; Macro to start a C callable function. This will be a far function for
- ; 16-bit code, and a near function for 32-bit code.
- MACRO cprocstatic name ; Set up model independant private proc
- ifdef flatmodel
- PROC name NEAR
- else
- PROC name FAR
- endif
- LocalSize = 0
- ENDM
- MACRO cprocstart name ; Set up model independant proc
- ifdef flatmodel
- ifdef __NOU__
- PROC name NEAR
- else
- PROC _&name& NEAR
- endif
- else
- ifdef __NOU__
- PROC name FAR
- else
- PROC _&name& FAR
- endif
- endif
- LocalSize = 0
- cglobalfunc name
- ENDM
- MACRO cprocnear name ; Set up near proc
- ifdef __NOU__
- PROC name NEAR
- else
- PROC _&name& NEAR
- endif
- LocalSize = 0
- cglobalfunc name
- ENDM
- MACRO cprocfar name ; Set up far proc
- ifdef __NOU__
- PROC name FAR
- else
- PROC _&name& FAR
- endif
- LocalSize = 0
- cglobalfunc name
- ENDM
- MACRO cprocend ; End procedure macro
- ENDP
- ENDM
- ; This macro sets up a procedure to be exported from a 16 bit DLL. Since the
- ; calling conventions are always _far _pascal for 16 bit DLL's, we actually
- ; rename this routine with an extra underscore with 'C' calling conventions
- ; and a small DLL stub will be provided by the high level code to call the
- ; assembler routine.
- MACRO cprocstartdll16 name
- ifdef __WINDOWS16__
- cprocstart _&name&
- else
- cprocstart name
- endif
- ENDM
- ; Macros for entering and exiting C callable functions. Note that we must
- ; always save and restore the SI and DI registers for C functions, and for
- ; 32 bit C functions we also need to save and restore EBX and clear the
- ; direction flag.
- MACRO save_c_regs
- ifdef flatmodel
- push ebx
- endif
- push _si
- push _di
- ENDM
- MACRO enter_c
- push _bp
- mov _bp,_sp
- IFDIFI <LocalSize>,<0>
- sub _sp,LocalSize
- ENDIF
- save_c_regs
- ENDM
- MACRO restore_c_regs
- pop _di
- pop _si
- ifdef flatmodel
- pop ebx
- endif
- ENDM
- MACRO leave_c
- restore_c_regs
- cld
- IFDIFI <LocalSize>,<0>
- mov _sp,_bp
- ENDIF
- pop _bp
- ENDM
- MACRO use_ebx
- ifdef flatmodel
- push ebx
- endif
- ENDM
- MACRO unuse_ebx
- ifdef flatmodel
- pop ebx
- endif
- ENDM
- ; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
- ; be used in assembly routines. This evaluates to nothing in the flat memory
- ; model, but is saves and restores DS in the large memory model.
- MACRO use_ds
- ifndef flatmodel
- push ds
- endif
- ENDM
- MACRO unuse_ds
- ifndef flatmodel
- pop ds
- endif
- ENDM
- MACRO use_es
- ifndef flatmodel
- push es
- endif
- ENDM
- MACRO unuse_es
- ifndef flatmodel
- pop es
- endif
- ENDM
- ; Macros for loading the address of a data pointer into a segment and
- ; index register pair. The macro explicitly loads DS or ES in the 16 bit
- ; memory model, or it simply loads the offset into the register in the flat
- ; memory model since DS and ES always point to all addressable memory. You
- ; must use the correct _REG (ie: _BX) macros for documentation purposes.
- MACRO _lds reg, addr
- ifdef flatmodel
- mov reg,addr
- else
- lds reg,addr
- endif
- ENDM
- MACRO _les reg, addr
- ifdef flatmodel
- mov reg,addr
- else
- les reg,addr
- endif
- ENDM
- ; Macros for adding and subtracting a value from registers. Two value are
- ; provided, one for 16 bit modes and another for 32 bit modes (the extended
- ; register is used in 32 bit modes).
- MACRO _add reg, val16, val32
- ifdef flatmodel
- add e®&, val32
- else
- add reg, val16
- endif
- ENDM
- MACRO _sub reg, val16, val32
- ifdef flatmodel
- sub e®&, val32
- else
- sub reg, val16
- endif
- ENDM
- ; Macro to clear the high order word for the 32 bit extended registers.
- ; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
- ; value, and will evaluate to nothing in 16 bit modes.
- MACRO clrhi reg
- ifdef flatmodel
- movzx e®&,reg
- endif
- ENDM
- MACRO sgnhi reg
- ifdef flatmodel
- movsx e®&,reg
- endif
- ENDM
- ; Macro to load an extended register with an integer value in either mode
- MACRO loadint reg,val
- ifdef flatmodel
- mov e®&,val
- else
- xor e®&,e®&
- mov reg,val
- endif
- ENDM
- ; Macros to load and store integer values with string instructions
- MACRO LODSINT
- ifdef flatmodel
- lodsd
- else
- lodsw
- endif
- ENDM
- MACRO STOSINT
- ifdef flatmodel
- stosd
- else
- stosw
- endif
- ENDM
- ; Macros to provide resb, resw, resd compatibility with NASM
- MACRO dclb count
- db count dup (0)
- ENDM
- MACRO dclw count
- dw count dup (0)
- ENDM
- MACRO dcld count
- dd count dup (0)
- ENDM
- ; Macros to provide resb, resw, resd compatibility with NASM
- MACRO resb count
- db count dup (?)
- ENDM
- MACRO resw count
- dw count dup (?)
- ENDM
- MACRO resd count
- dd count dup (?)
- ENDM
- ; Macros to declare assembler stubs for function structures
- MACRO BEGIN_STUBS_DEF name, firstOffset
- begdataseg _STUBS
- ifdef __NOU_VAR__
- EXTRN name:DWORD
- STUBS_START = name
- else
- EXTRN _&name&:DWORD
- name EQU _&name&
- STUBS_START = _&name
- endif
- enddataseg _STUBS
- begcodeseg _STUBS
- off = firstOffset
- ENDM
- MACRO DECLARE_STUB name
- ifdef __NOU__
- name:
- PUBLIC name
- else
- _&name:
- PUBLIC _&name
- endif
- jmp [DWORD STUBS_START+off]
- off = off + 4
- ENDM
- MACRO DECLARE_STDCALL name,num_args
- ifdef STDCALL_MANGLE
- _&name&@&num_args&:
- PUBLIC _&name&@&num_args&
- else
- name:
- PUBLIC name
- endif
- jmp [DWORD STUBS_START+off]
- off = off + 4
- ENDM
- MACRO END_STUBS_DEF
- endcodeseg _STUBS
- ENDM
- MACRO BEGIN_IMPORTS_DEF name
- BEGIN_STUBS_DEF name,4
- ENDM
- MACRO DECLARE_IMP name
- DECLARE_STUB name
- ENDM
- MACRO END_IMPORTS_DEF
- END_STUBS_DEF
- ENDM
- endif
|