; Copyright (c) 1998 Microsoft Corporation ; ; @Doc DMusic16 ; ; @Module DMHelp.asm - Helper functions | ; ; Thunk helpers for DMusic16.DLL ; page ,132 TITLE $dos\usa\dmhelp.asm .386 OPTION READONLY OPTION OLDSTRUCTS OPTION SEGMENT:USE16 .model LARGE,PASCAL ;?MEDIUM=1 ;?QUIET=1 externDef TileBuffer:far16 externDef UntileBuffer:far16 externDef OutputDebugString:far16 ;=========================================================================== ; ; 64-bit integer struct as passed in from C routines ; ; This must match the definition in dmusic16.h ; ; ;=========================================================================== QUADWORD struc qwLow dd ? qwHigh dd ? QUADWORD ends .code dmhelp ;=========================================================================== EAXtoDXAX macro shld edx, eax, 16 ; move HIWORD(eax) to dx endm DXAXtoEAX macro ror eax, 16 ; xchg HIWORD(eax) and LOWORD(eax) shrd eax, edx, 16 ; move LOWORD(edx) to HIWORD(eax) endm ;=========================================================================== public dmTileBuffer public dmUntileBuffer public QuadwordDiv externDef __FLATDS:abs _DATA SEGMENT WORD USE16 PUBLIC 'DATA' FlatData dw __FLATDS ifdef DEBUG szNotOwner db 'Critical section released by other than owner', 0 endif _DATA ENDS ;=========================================================================== ; ; @func DWORD | dmTileBuffer | Tile a 32-bit linear address as selectors ; ; @comm ; ; Take the 32-bit virtual address in
of length
and create
; tiled selectors for it. This is used to pass a region of memory to a 16 bit thunk
; as a huge pointer.
;
; @rdesc
;
; Returns a DWORD of tiling information, or 0 if the tiling could not be completed.
; The tiling information consists of a 16 bit selector in the high word and the
; number of tiled selectors in the low word. To make a 16:16 pointer to the
; block of memory, mask the low 16 bits of the tiling information to zero.
;
; @parm DWORD | dwFlatMemory | The linear address of the memory to tile
;
; @parm DWORD | dwLength | The length in bytes of the region to tile
;
align
dmTileBuffer proc far16 public,
dwFlatMemory:dword, dwLength:dword
push edi
push esi
mov eax, dwFlatMemory
mov ecx, dwLength
call TileBuffer
mov eax, ecx
EAXtoDXAX
pop esi
pop edi
ret
dmTileBuffer endp
;===========================================================================
;
; @func VOID | dmUntileBuffer | Untile a buffer
;
; @comm
;
; Free the tiled selectors allocated by dmTileBuffer. The buffer must have
; been previously tiles with and giving a 64-bit result
; in .
;
; @rdesc
; Returns m1 * m2
;
; @parm DWORD | m1 | First multiplicand
; @parm DWORD | m2 | Second multiplicand
; @parm LPQUADWORD | lpqwResult | 64-bit result
;
QuadwordMul proc far16 public,
m1 : dword,
m2 : dword,
lpqwResult : dword
mov edx, [m1]
mov eax, [m2]
mul edx
les bx, [lpqwResult]
mov es:[bx.qwLow], eax
mov es:[bx.qwHigh], edx
ret
QuadwordMul endp
;===========================================================================
;
; @func DWORD PASCAL | QuadwordDiv | Divide using 64-bit precision
;
; @comm
;
; Divide the 64-bit number in by the 32-bit number in and
; return the result. May throw a divide by zero exception.
;
; @rdesc
; Returns ull / dwDivisor
;
; @parm QUADWORD | ull | The unsigned long dividend
; @parm DWORD | dwDivisor | The divisor
;
;
QuadwordDiv proc far16 public,
qwDividend : QUADWORD,
dwDivisor : dword
mov edx, [qwDividend.qwHigh]
mov eax, [qwDividend.qwLow]
mov ebx, [dwDivisor]
div ebx
; Result in eax, needs to be dx:ax for 16-bit code
ror eax, 16
mov dx, ax
ror eax, 16
ret
QuadwordDiv endp
;===========================================================================
;
; @func DWORD PASCAL | QuadwordLT | Compare two quadwords for less than (unsigned)
;
; @rdesc
; Returns TRUE if qwLValue < qwRValue
;
; @parm QUADWORD | qwLValue | The first operand of less-than
; @parm QUADWORD | qwRValue | The second operand of less-than
;
;
QuadwordLT proc far16 public,
qwLValue : QUADWORD,
qwRValue : QUADWORD
mov ebx, [qwLValue.qwHigh]
sub ebx, [qwRValue.qwHigh]
jz short @F
sbb eax, eax
ret
@@: mov ebx, [qwLValue.qwLow]
sub ebx, [qwRValue.qwLow]
sbb eax, eax
ret
QuadwordLT endp
;===========================================================================
;
; @func DWORD PASCAL | QuadwordAdd | Add two unsigned quadwords
;
; @parm QUADWORD | qwOp1 | The first operand
; @parm QUADWORD | qwOp2 | The second operand
; @parm LPQUADWORD | lpwqResult | The result
;
;
QuadwordAdd proc far16 public,
qwOp1 : QUADWORD,
qwOp2 : QUADWORD,
lpdwResult : DWORD
mov eax, [qwOp1.qwLow]
add eax, [qwOp2.qwLow]
mov edx, [qwOp1.qwHigh]
adc edx, [qwOp2.qwHigh]
les bx, [lpdwResult]
mov es:[bx.qwLow], eax
mov es:[bx.qwHigh], edx
ret
QuadwordAdd endp
end