windows-nt/Source/XPSP1/NT/multimedia/media/avi/inc.16/model.inc

232 lines
5.3 KiB
PHP
Raw Normal View History

2020-09-26 03:20:57 -05:00
; ========================================================
;
; MODEL.INC
;
; Copyright (c) 1991 - Microsoft Corp.
; All rights reserved.
; Microsoft Confidential
;
;
; Include file which allows globally controlling the memory
; model of a library of assembly modules. Also contains
; macros for writing MASM 6.0 code which will compile
; under DOS 5.1.
;
;
; johnhe - 01-24-92
;
; ========================================================================
; Default to small memory model and C calling conventions if none
; were declared.
;
; ========================================================================
; Convert old build switches to new type
IFDEF MODEL_LARGE
MEM_MODEL EQU <LARGE>
ELSEIFDEF MODEL_MEDIUM
MEM_MODEL EQU <MEDIUM>
ELSEIFDEF MODEL_COMPACT
MEM_MODEL EQU <COMPACT>
ELSEIFDEF MODEL_SMALL
MEM_MODEL EQU <SMALL>
ENDIF
IFNDEF MEM_MODEL
MEM_MODEL EQU <SMALL>
ENDIF
IFNDEF CALL_TYPE
CALL_TYPE EQU <C>
ENDIF
; ========================================================================
; The following defines the memory model based on one of four constants
; being defined. If none of the constants have been defined the model
; will default to MODEL_SMALL
; ========================================================================
DOSSEG
.MODEL MEM_MODEL,CALL_TYPE
; ========================================================================
; This macro allows writing code which will assemble with MASM 5.1 or
; 6.0. MASM 6.0 requires an assume statement before using a register
; as the base pointer of a structure.
;
; RegPtr Register:STRUC, Register:STRUC, ...
;
; EXAMPLE:
;
; RegPtr DI:MyStruc
;
; ========================================================================
RegPtr MACRO arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
IFB <arg1>
%out <Assume Macro --> Requires at least 1 argument.>
ENDIF
IF @Version GE 600
IRP X, <arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9>
IFNB <x>
ASSUME x
ENDIF
ENDM
ENDIF
ENDM
; ========================================================================
; Macro which exsplicitly calls a far or near procedure based on the
; current memory model.
;
; call_M PROCEDURE_NAME
;
; ========================================================================
call_M MACRO Function
IF @codesize ; Call adjusted for memory model
call FAR PTR Function ; FAR call if LARGE, MED, or HUGE
ELSE
call NEAR PTR Function ; Else NEAR call
ENDIF
ENDM
; ========================================================================
; DS_IF_DATASIZE
;
; Equate to allow DS to be pushed on entry to a function if ptrs are
; far. This macro should be used in conjunction with LoadPtr DS,x,x
; to ensure DS will be saved if its destroyed by a far ptr load.
;
; EXAMPLE:
;
; Function PROC USES DI SI ES FPTR_DS, Buffer:PTR, EndBuf:PTR
;
; LoadPtr ES,DI,EndBuf
; LoadPTr DS,SI,BUffer
; ...
; Function ENDP
;
; Function PROC USES_FPTR_DS, Buffer:PTR, EndBuf:PTR
;
; LoadPtr ES,DI,EndBuf
; LoadPTr DS,SI,BUffer
; ...
; Function ENDP
;
; ========================================================================
IF @DATASIZE
FPTR_DS EQU <DS>
USES_FPTR_DS EQU <USES DS>
DS_IF_DATASIZE EQU <DS>
ELSE
FPTR_DS EQU <>
USES_FPTR_DS EQU <>
DS_IF_DATASIZE EQU <>
ENDIF
; ========================================================================
; LoadPtr
;
; Macro to load a pointer based on the memory model that is in use.
; Argument checking is included in the macro and the appropriate
; error message will be displayed.
;
; LoadPtr MACRO vSegReg, vReg, vPtr
;
; vSegReg - Segment register (normally DS or ES but may be any)
; vReg - Any general purpose register (AX,BX,CX,DX,SI,DI)
; vPtr - Pointer to a memory location.
; The value will be treated as a dword ptr in
; LARGE/COMPACT model and word ptr in MEDIUM/SMALL.
;
; ========================================================================
LoadPtr MACRO vSegReg, vReg, vPtr
SEG_OK = 0 ;; Variables to specify different errors
REG_OK = 0
PTR_OK = 0
;; Error checking on segment register
IFNB <vSegReg>
IRP x, <ES,DS,AX,BX,CX,DX,SI,DI>
IFIDNI <x>,<vSegReg>
SEG_OK = 1
ENDIF
ENDM
ENDIF
;; Error checking on index register
IFNB <vReg>
IRP y, <AX,BX,CX,DX,SI,DI>
IFIDNI <y>,<vReg>
REG_OK = 1
ENDIF
ENDM
ENDIF
;; Error checking on memory pointer
IFNB <vPtr>
PTR_OK = 1
ENDIF
;; If errs found display appropriate message
IF (SEG_OK + REG_OK + PTR_OK) NE 3
IF SEG_OK EQ 0
%out <LoadPtr Macro --> Invalid segment register vSegReg was specified.>
ENDIF
IF REG_OK EQ 0
%out <LoadPtr Macro --> Invalid register vReg was specified.>
ENDIF
IF PTR_OK EQ 0
%out <LoadPtr Macro --> No memory pointer was specified.>
ENDIF
.ERR
ELSE ;; Start of code in the macro since no errs found
IF @DataSize ;; For LARGE & COMPACT models use LDS or LES opcodes
IFIDNI <vSegReg>,<DS>
lds vReg, vPtr
ELSEIFIDNI <vSegReg>,<ES>
les vReg, vPtr
ELSE
mov vSegReg, WORD PTR vPtr[2]
mov vReg, WORD PTR vPtr
ENDIF
ELSE
;; If vSegReg == ES we have to set ES to DATA SEG
IFIDNI <vSegReg>,<ES>
push DS
pop ES
ENDIF
;; Load pointer into specified register
mov vReg, vPtr
ENDIF
ENDIF
ENDM