home *** CD-ROM | disk | FTP | other *** search
- %noincl
- ; Memory-model dependent equates and macros
-
- ; ----- True/false equates -----
-
- @isCodeNear = (@CodeSize eq 0) and 1
- @isDataNear = (@DataSize eq 0) and 1
- @isDataFar = @isDataNear xor 1
- @isStackNear INSTR 1,@data,@stack
- @isStackFar = @isStackNear xor 1
- ; Next line required for Borland C++
- @isStackFar = @isStackFar or @isDataFar
- @is386 = (@Cpu shr 3) and 1 ; .386+ instructions
- @isUse32 INSTR 1,@data,<FLAT>
- @isWin32 = @isUse32 ; NOTE
-
- ife @isWin32
- @isDirectionUp = 0 ; Zero if
- @isDSeqESeqSS = 0 ; don't know
- else ; Must be set for Win32
- @isDirectionUp = 1 ; 1: assume direction flag clear
- @isDSeqESeqSS = 1 ; 1: assume DS = ES = SS
- endif
-
-
- ; ----- Text equates -----------
-
- @bptr equ <byte ptr>
- @wptr equ <word ptr>
- @uiptr equ <@uint ptr>
- sh equ <short>
- if @isDSeqESeqSS
- @ES equ <>
- else
- @ES equ <es:>
- endif
-
-
- ife @isUse32
- @uint equ <word>
- @dui equ <dw>
- rax equ <ax>
- rcx equ <cx>
- rdx equ <dx>
- rbx equ <bx>
- rsp equ <sp>
- rbp equ <bp>
- rsi equ <si>
- rdi equ <di>
- else
- @uint equ <dword>
- @dui equ <dd>
- rax equ <eax>
- rcx equ <ecx>
- rdx equ <edx>
- rbx equ <ebx>
- rsp equ <esp>
- rbp equ <ebp>
- rsi equ <esi>
- rdi equ <edi>
- endif
-
-
- ; KLUDGES! to make TASM's extended CALL work with either
- ; near or far data, as dataptr(segm::offs) isn't supported.
- ; (Feel free to e-mail me a smart invoke macro.)
- ;
- ; e.g.: call WriteZStr, @dsaddr(msg)
- ; call bcdCmpz, @dsr(si), 10
- ;
- if @isDataNear ; With CALL:
- @nullptr equ <0>
- @dsaddr equ <offset> ; push offset(msg)
- @dsr equ <> ; push (si)
- if @isStackNear
- @ssr equ <>
- endif
- else
- @nullptr equ <0 0>
- @dsaddr equ <ds offset> ; push ds offset(msg)
- @dsr equ <ds offset> ; push ds offset(si) ; = push ds si
- @ssr equ <ss offset>
- endif
-
-
- ; ----- Macros -----------------
-
- @CODESEG MACRO
- if @isCodeNear ;; Near: segment name _TEXT
- .code
- else ;; Segment name of far code
- % .code @fartext
- endif
- endm
-
- ;
- ; Align code for speed,
- ; use if large-sized BCDs
- ;
- @alignn MACRO
- align @WordSize
- endm
-
- ;
- ; Define procedure type (named @Type_procname)
- ;
- @ptype MACRO procname, ahrgs:REST
- @Type_&procname proctype ahrgs
- endm
-
- ;
- ; Define procedure type (named @Type_procname)
- ; and make procname public or extrn
- ;
- @proto MACRO procname, ahrgs:REST
- procname procdesc ahrgs
- endm
-
- ;
- ; Selective USES statement that picks unneeded items
- ; off the push/pop list. It looks dangerous, and it is.
- ;
- @uses MACRO savelist:VARARG
- local ulist,delim,pn,saveit
- ulist equ <>
- delim equ <>
- irp pn,<savelist>
- ifnb <pn>
- saveit = 1 ;; Default: preserve register
- ifidni <pn>,<ds> ;; Skip DS if neardata and nearstack
- saveit = @isDataFar OR @isStackFar
- elseifidni <pn>,<es> ;; Skip ES unless 32-bit non-flat
- if @isDSeqESeqSS
- saveit = 0
- else
- saveit = @isUse32
- endif
- elseifidni <pn>,<rbx> ;; Skip BX if 16-bit code
- saveit = @isUse32
- elseifidni <pn>,<rsi> ;; Skip SI if 16-bit Pascal
- saveit = @isUse32 OR ((@Interface and 7Fh) ne 4)
- elseifidni <pn>,<rdi> ;; Skip DI if 16-bit Pascal
- saveit = @isUse32 OR ((@Interface and 7Fh) ne 4)
- elseifidni <pn>,<rdx> ;; Skip eDX, eCX, eAX
- saveit = 0
- elseifidni <pn>,<rcx>
- saveit = 0
- elseifidni <pn>,<rax>
- saveit = 0
- else
- %out Bad USES parameter
- .err
- endif
- if saveit
- ulist CATSTR ulist,delim,<pn>
- delim equ <,>
- endif
- endif
- endm ;; irp pn
- ifnb <ulist>
- % uses ulist
- endif
- endm ;; macro
-
- ;
- ; All segment register loads are
- ; made using @LDSEGM, @LDS, or @LES
- ;
- @LDSEGM MACRO dstseg, srcseg, genreg
- local skip
- if @isDSeqESeqSS ;; Ignore ds:=ss,es:=ds,es:=ss
- skip = 0
- ifidni <dstseg>,<es>
- skip = 1
- elseifidni <dstseg>,<ds>
- skip = 1
- endif
- if skip
- ifidni <srcseg>,<ds>
- exitm
- elseifidni <srcseg>,<ss>
- exitm
- endif
- endif
- endif
- ifnb <genreg> ;; Move thru general register
- mov genreg, srcseg
- mov dstseg, genreg
- else
- push srcseg
- pop dstseg
- endif
- endm
-
- @LDS MACRO genreg, mem
- if @isDataNear
- mov genreg, mem
- else
- lds genreg, mem
- endif
- endm
-
- @LES MACRO genreg, mem
- if @isDataNear
- mov genreg, mem
- @LDSEGM es, ds
- else
- les genreg, mem
- endif
- endm
-
-
- @cld MACRO
- ife @isDirectionUp
- cld
- endif
- endm
-
- @shl MACRO reg, count
- shl reg, count ;; TASM REPTs if .8086
- endm
-
- @shr MACRO reg, count
- shr reg, count ;; TASM REPTs if .8086
- endm
-
- ;
- ; TASM's automatic stack frames use ENTER and LEAVE
- ; unless the 8086 processor is selected. For speed
- ; and/or size, it's better to use push/mov/sub.
- ;
- pushstate
- nowarn RES ; Reserved word warnings off
- ENTERW MACRO loc, lex
- @enter loc, lex
- endm
-
- ENTERD MACRO loc, lex
- @enter loc, lex
- endm
-
- LEAVEW MACRO
- @leave
- endm
-
- LEAVED MACRO
- @leave
- endm
- popstate ; Restore warning state
-
- @enter MACRO loc, lex
- if lex eq 0
- @fram = 2
- push rbp
- mov rbp, rsp
- if loc gt 0
- @fram = 3
- if loc eq @WordSize
- push rax
- else
- sub rsp, loc
- endif
- endif
- else
- @fram = 4
- enter loc, lex
- endif
- endm
-
- @leave MACRO
- .erre @fram ;; leave without enter
- if @fram and 4
- leave
- else
- if @fram and 1
- mov rsp, rbp
- endif
- pop rbp
- endif
- @fram = 0
- endm
-
- ; end of include
-