home *** CD-ROM | disk | FTP | other *** search
- ; Macros definition file (instruction / directives extensions).
-
- ; $Id: Instr32.mac 1.2 1997/09/02 11:39:24 Philippe Exp $
-
- ; $Log: /Win32Equ/Instr32.mac $
- ;
- ; 1 18/09/97 14:24 Philippe
- ; Initial checkin into SourceSafe.
- ; Revision 1.2 1997/09/02 11:39:24 Philippe
- ; Added HighItem optional parm to ENUMEND macro.
- ;
- ; Revision 1.1 1997/09/02 09:50:38 Philippe
- ; Initial revision
- ;
-
-
-
- ; MASM 6.x Structured coding directives extensions.
-
- OPTION DOTNAME ;Allow names such as .BLOCK
- OPTION PROC:PRIVATE ;PROCs are private by default.
-
- ; The .BLOCK/.ENDBLOCK directives provide a non-looping, non generating
- ; frame that can be used for generating a block with multiway exits to
- ; a single point (thru .BREAK .IF <condition> directives).
-
- .BLOCK MACRO ;; Begin code block.
- .REPEAT
- ENDM
-
- .ENDBLOCK MACRO ;; End code block.
- .UNTIL 1 ;; (Generates no code.)
- ENDM
-
-
- ; More readable/explicit than .UNTIL 0 or .UNTIL FALSE.
-
- .FOREVER MACRO ;; Loop forever (.REPEAT / .FOREVER)
- .UNTIL 0 ;;
- ENDM
-
- ; The Microserfs who did MASM didn't take the obvious decision of simply
- ; deriving the Intel J<cond> mnemonics for simple condition testing in their
- ; structured programming directive (like allowing .IF AE?, .WHILE GE?,
- ; .UNTIL BE?, .BREAK .IF A?, whatever...).
- ; So it looks like there is no simple way to use the directives to generate
- ; some of the jumps from preexisting conditions.
- ; But for those that are supported (and their NOT form), here are a few
- ; additional mnemonics:
-
- EQUAL? TEXTEQU <ZERO?>
- BELOW? TEXTEQU <CARRY?>
- ABOVEorEQUAL? TEXTEQU <!!CARRY?>
-
-
-
- ; This macro because of a silly bug in MASM:
- ; MASM does generate a LINK directive in a module object code that has an
- ; END Label
- ; directive. The problem is, it does it wrong <sigh>.
- ; If an STDCALL directive is in effect, and the entry procedure is Start,
- ; the "END Start" directive will generate an inline
- ; /Entry:_Start"
- ; directive.
- ; Now, note that LINK will in turn decorate the name and internally change
- ; it to "__Start", that it expects to be a PUBLIC in the object file.
- ; The net result is that an END Start will generate a reference to __Start.
- ;
- ; Strike 2: There can't be neither _Start nor __Start defined in the MASM
- ; module, because the use of STDCALL will change any "Start" PROC
- ; in the source into a PUBLIC reference of _Start@0.
- ; So we endup with MASM declaring _Start@0 and referencing __Start.
- ; The error here is in the embedded link directive the END statement generates.
- ; If MASM were consistent with itself, it would apply the default interface
- ; convention for the module to the END directive, thus generating an inline
- ; /Entry:_Start@0
- ; link directive for everything to be fine. But even though MASM is not
- ; consistent with itself, we can fix the problem, by replacing the END
- ; directive with the following Entry macro:
- ; ENTRY Start
- ; This macro will only work with the STDCALL parms convention (the one Win32
- ; uses). It would be easy to test for the parm passing model and generate
- ; the proper code for other conventions.
-
- ENTRY MACRO EntryPoint:REQ
- LOCAL EntryPoint
- IF @Version GE 611
- ALIAS <_&EntryPoint&@0>=<&EntryPoint>
- ENDIF
- END &EntryPoint
- ENDM
-
-
- ; SAVE & RESTORE. - Ph.A., 16.05.86.
- ; SAVE : Save registers to the stack.
- ; RESTORE: Restore registers from the stack.
- ; RESTORE generates POPs from the parm list in backward order, so the same
- ; list that was used for a SAVE can be used to restore the registers to
- ; their SAVED values.
- ; Changed to generate PUSHFD / POPFD for 32 bits.
-
- SAVE MACRO R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,TESTARG
- .ERRNB <TESTARG> ;Too many things to push.
- IFNB <R1>
- IFIDNI <R1>,<F>
- PUSHFD
- ELSE
- PUSH R1
- ENDIF
- SAVE R2,R3,R4,R5,R6,R7,R8,R9,R10,R11
- ENDIF
- ENDM
- .XCREF SAVE
-
- RESTORE MACRO R11,R10,R9,R8,R7,R6,R5,R4,R3,R2,R1,TESTARG
- .ERRNB <TESTARG> ;Too many things to pop.
- IFNB <R11>
- RESTORE R10,R9,R8,R7,R6,R5,R4,R3,R2,R1
- IFIDNI <R11>,<F>
- POPFD
- ELSE
- POP R11
- ENDIF
- ENDIF
- .CREF
- ENDM
- .XCREF RESTORE
-
-
- ; Dummy macro used to suppress MASM warning about unused parms (declared
- ; in function headers but actually not used in a proc).
-
- UnusedParm Macro ParmName:REQ
- Local Dummy
- Dummy EQU ParmName ;Fool MASM by using parm.
- ENDM
-
-
- ; MUSTBE & SHOULDBE macros - Ph.A., 26.05.86.
-
- ; MUSTBE & SHOULDBE are called with a valid condition mnemonic value, such
- ; as A, NZ, NGE. If the required condition is not met, MUSTBE calls the
- ; FATALERR routine, which is a no-return, ABEND type of routine, and SHOULDBE
- ; calls the WARNING routine, which would probably be implemented as a snapshot
- ; dump or trace routine, and would return control.
-
- MUSTBE MACRO C1
- Local Around
- FatalError PROTO STDCALL MsgAddr:DWORD
- IFNB <C1>
- J&C1 SHORT Around ;Jump around lethal call.
- ENDIF
- INVOKE FatalError,0 ;Die horribly.
- IFNB <C1>
- Around:
- ENDIF
- ENDM
- .XCREF MUSTBE
-
-
- MUSTBEM MACRO C1,MSG
- Local szMsg,Around
- FatalError PROTO STDCALL MsgAddr:DWORD
- .XCREF
- IFNB <C1> ;If cond defined and met,
- J&C1 Around ;Jump around jump the lethal call
- ENDIF
- IFB <MSG>
- INVOKE FatalErr,0 ;No error message this time
- ELSE
- .CONST
- BYTE SIZEOF szMsg
- szMsg BYTE MSG,0 ;Give error msg.
- .CODE
- INVOKE FatalError,ADDR szMsg
- ENDIF
- IFNB <C1>
- Around:
- ENDIF
- ENDM
- .XCREF MUSTBEM
-
- MUSTBEMGLE MACRO C1,MSG
- Local szMsg,Around
- FatalErrorGLE PROTO STDCALL MsgAddr:DWORD
- .XCREF
- IFNB <C1> ;If cond defined and met,
- J&C1 Around ;Jump around jump the lethal call
- ENDIF
- IFB <MSG>
- INVOKE FatalErrorGLE,0
- ELSE
- .CONST
- BYTE SIZEOF szMsg
- szMsg BYTE MSG,0 ;Give error msg
- .CODE
- INVOKE FatalErrorGLE,ADDR szMsg
- ENDIF
- IFNB <C1>
- Around:
- ENDIF
- ENDM
- .XCREF MUSTBEMGLE
-
-
- SHOULDBE MACRO C1
- Local Around
- Warning PROTO STDCALL
- IFNB <C1>
- J&C1 SHORT Around ;Jump around warning call.
- ENDIF
- INVOKE Warning ;Indicate some strange condition.
- IFNB <C1>
- Around:
- ENDIF
- ENDM
- .XCREF SHOULDBE
-
-
- ; Define enumerated, sequential equate values.
- ; Useful for defining indices or offset into tables.
- ; Example of use:
- ;
- ; ENUM WORD
- ; ENUMITEM FBTxStIdle ;TXer does plenty of nothing.
- ; ENUMITEM FBTxStHead2 ;About to send 'B', second header byte.
- ; ENUMITEM FBTxStData ;About to send a data byte.
- ; ENUMITEM FBTxStCRC8 ;TxEr about to send CRC-8 (negociation).
- ; ENUMITEM FBTxStCRC16L ;TxEr about to send CRC-16, LSB
- ; ENUMITEM FBTxStCRC16M ;TxEr about to send CRC-16, MSB
- ; ENUMITEM FBTxStDLEd ;TXer about to send DLE'd data.
- ; ENUMITEM FBTxStRing ;Transmitting from ring buffer.
- ; ENUMITEM FBTxStChain ;Txer about to check for chained
- ; ;transmission.
- ; ENUMEND Foo ;Foo (optional arg) is a symbol that
- ; ;will be equated to the value
- ; ;of the highest item generated.
-
-
- ENUM MACRO ItemType:REQ
- LOCAL ItemType
- IFDEF $$$ItemValue
- .ERRNZ $$$ItemValue - (-1) ; Wrong ENUM macros nesting
- ENDIF
- $$$ItemSize = SIZEOF ItemType
- $$$ItemValue = 0
- ENDM
-
- ENUMITEM MACRO ItemName:REQ
- LOCAL ItemName
- .ERRNZ ($$$ItemValue EQ -1) ;Missing ENUM macro.
- ItemName = $$$ItemValue
- $$$ItemValue = $$$ItemValue + $$$ItemSize
- ENDM
-
- ENUMEND MACRO HighItem
- Local HighItem
- IFNB <HighItem> ;If HighItem is defined,
- HighItem = $$$ItemValue - $$$ItemSize ;Equate the symbol with highitem
- ENDIF ;value.
- .ERRNZ ($$$ItemValue EQ -1) ;Wrong ENUM macros nesting.
- $$$ItemValue = -1
- ENDM
-
-
- ; For compatibility with older stuff.
- ; For long strings, use the MEMMOVE routine that moves aligned DWORDs
-
- BXFER MACRO
- REP MOVSB
- ENDM
-
-
- ; Breakpoint instructions. Ph.A.
- ; Breakpoint may be implemented thru INT 3 (one byte interrupt) or INT 2
- ; (NMI).
-
- BREAK MACRO
- INT 3 ;Use Breakpoint interrupt.
- ENDM
- .XCREF BREAK
-
- DEBUG MACRO
- INT 1 ;Use Debugger Call interrupt.
- ENDM
- .XCREF DEBUG
-
- NMI MACRO
- INT 2 ;Use NMI interrupt.
- ENDM
- .XCREF NMI
-
-
- ; For use between back-to-back I/O to the same chip (for AT compatibility).
- ; Should add yet another JMP SHORT $+2 to make provision for fast processors
- ; and slow busses (it purges the instruction prefetch queue).
- ; How much of these will we need for 486 ?!
- ; Is this still enough with 586 branch prediction ? Ph.A.
-
- IODELAY MACRO
- JMP SHORT @F
- @@:
- ENDM
- .XCREF IODELAY
-
-