680 lines
17 KiB
NASM
Executable File
680 lines
17 KiB
NASM
Executable File
PAGE 58,132
|
|
|
|
.386p
|
|
|
|
;
|
|
; Client has:
|
|
; States -> state is set by writing to port
|
|
; data is retrieved by reading from port
|
|
;
|
|
; State 0: Get Identification "ITVXDDRV"
|
|
; State 1: Get Server string (64 bytes)
|
|
; State 2: Get buffer used
|
|
; State 3: Reset Client
|
|
; State 4: Get debug value
|
|
; State 5: Get TSC
|
|
;
|
|
;
|
|
; Server interface:
|
|
; Write 0 to reset
|
|
; If read, returns "ITSERVER", else 01h if Server has been validated.
|
|
; Needs to receive "ITSERVER" to validate.
|
|
; If validated, receives server string of max 64 bytes, no 0 permitted.
|
|
;
|
|
|
|
|
|
.XLIST
|
|
INCLUDE VMM.Inc
|
|
INCLUDE Debug.Inc
|
|
INCLUDE Shell.inc
|
|
.LIST
|
|
|
|
VSound_Client_Address EQU 400h
|
|
VSound_Server_Address EQU 401h
|
|
VSound_Data_Address EQU 402h
|
|
|
|
VSOUND_CLIENTSTATES EQU 7
|
|
VSOUND_BUFFERSIZE EQU (64*1024)
|
|
|
|
;******************************************************************************
|
|
; V I R T U A L D E V I C E D E C L A R A T I O N
|
|
;******************************************************************************
|
|
|
|
Declare_Virtual_Device VSOUND, 1, 0, VSOUND_Control, Undefined_Device_ID ,,,
|
|
|
|
;******************************************************************************
|
|
; L O C A L D A T A
|
|
;******************************************************************************
|
|
|
|
|
|
VxD_LOCKED_DATA_SEG
|
|
|
|
VSound_Data DB VSOUND_BUFFERSIZE Dup (0)
|
|
VSound_HeadPointer DD 0
|
|
VSound_TailPointer DD 0
|
|
|
|
VSound_Client DD 0
|
|
VSound_Server DD 0
|
|
VSound_ClientCallback DD 0
|
|
|
|
VSound_ID DB "ITVXDDRV"
|
|
VSound_State DD 0
|
|
VSound_BufferUsed DD 0
|
|
VSound_StatePos DD 0
|
|
|
|
VSound_ServerID DB "ITSERVER"
|
|
VSound_ServerInPos DD 0
|
|
VSound_ServerOutPos DD 0
|
|
VSound_ServerValid DD 0
|
|
|
|
VSound_DebugValue DD 0
|
|
VSound_TimeStamp1 DD 0
|
|
VSound_TimeStamp2 DD 0
|
|
|
|
VSound_InTable DD Offset32 VSound_Identification
|
|
DD Offset32 VSound_GetServerString
|
|
DD Offset32 VSound_GetBufferUsed
|
|
DD Offset32 VSound_GetDebugValue
|
|
DD Offset32 VSound_Get0
|
|
DD Offset32 VSound_GetDebugValue
|
|
DD Offset32 VSound_GetTSC
|
|
|
|
VSound_OutTable DD Offset32 VSound_Out_ResetStatePos
|
|
DD Offset32 VSound_Out_ResetStatePos
|
|
DD Offset32 VSound_Out_GetBufferUsed
|
|
DD Offset32 VSound_Out_ResetClient
|
|
DD Offset32 VSound_Out_SetCallbackAddress
|
|
DD Offset32 VSound_Out_ResetStatePos
|
|
DD Offset32 VSound_Out_GetTSC
|
|
|
|
VSound_ServerString DB 64 Dup (0)
|
|
|
|
VxD_LOCKED_DATA_ENDS
|
|
|
|
|
|
;******************************************************************************
|
|
; I N I T I A L I Z A T I O N C O D E
|
|
;******************************************************************************
|
|
|
|
VxD_IDATA_SEG
|
|
|
|
Begin_Vxd_IO_Table IO_Table
|
|
Vxd_IO VSound_Client_Address, VSound_Client_Hook
|
|
Vxd_IO VSound_Server_Address, VSound_Server_Hook
|
|
Vxd_IO VSound_Data_Address, VSound_Data_Hook
|
|
End_Vxd_IO_Table IO_Table
|
|
|
|
VxD_IDATA_ENDS
|
|
|
|
VxD_ICODE_SEG
|
|
|
|
|
|
;******************************************************************************
|
|
;
|
|
; VSOUND_Device_Init
|
|
;
|
|
; DESCRIPTION:
|
|
;
|
|
; This routine is called during Windows startup. It needs to
|
|
; install the I/O handler for our device, and set up the system
|
|
; VM as the default owner.
|
|
;
|
|
;
|
|
;==============================================================================
|
|
|
|
BeginProc VSOUND_Device_Init
|
|
|
|
Xor EAX, EAX
|
|
Mov VSound_Client, EAX ; no current owner
|
|
Mov VSound_Server, EAX ; no current owner
|
|
Mov VSound_ClientCallback, EAX ; No callback
|
|
|
|
Mov EDI, OFFSET32 IO_Table
|
|
VMMCall Install_Mult_IO_Handlers
|
|
|
|
Ret
|
|
|
|
EndProc VSOUND_Device_Init
|
|
|
|
VxD_ICODE_ENDS
|
|
|
|
|
|
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
VxD_CODE_SEG
|
|
|
|
;******************************************************************************
|
|
;
|
|
; VSOUND_Destroy_VM
|
|
;
|
|
; DESCRIPTION:
|
|
;
|
|
; This routine is called when a VM is destroyed. We need to check
|
|
; to see if the VM in question is the current owner of the device.
|
|
;
|
|
;==============================================================================
|
|
|
|
BeginProc VSOUND_Destroy_VM
|
|
|
|
Xor EAX, EAX
|
|
|
|
Cmp EBX, VSound_Client ; Destroying device owner?
|
|
JNE Short VDM_Client
|
|
|
|
Mov VSound_Client, EAX
|
|
Mov VSound_ClientCallback, EAX
|
|
|
|
VDM_Client:
|
|
Cmp EBX, VSound_Server
|
|
JNE VDM_Server
|
|
|
|
Mov VSound_Server, EAX
|
|
Mov VSound_ServerValid, EAX
|
|
|
|
VDM_Server:
|
|
ClC
|
|
Ret
|
|
|
|
EndProc VSOUND_Destroy_VM
|
|
|
|
VxD_CODE_ENDS
|
|
|
|
|
|
;******************************************************************************
|
|
|
|
VxD_LOCKED_CODE_SEG
|
|
|
|
;******************************************************************************
|
|
;
|
|
; VSound_Control
|
|
;
|
|
; DESCRIPTION:
|
|
;
|
|
; This is a call-back routine to handle the messages that are sent
|
|
; to VxD's to control system operation.
|
|
;
|
|
;==============================================================================
|
|
BeginProc VSound_Control
|
|
|
|
Control_Dispatch Device_Init, VSound_Device_Init
|
|
Control_Dispatch Destroy_VM, VSound_Destroy_VM
|
|
|
|
ClC
|
|
Ret
|
|
|
|
EndProc VSound_Control
|
|
|
|
VxD_LOCKED_CODE_ENDS
|
|
|
|
|
|
VxD_CODE_SEG
|
|
|
|
;*****************************************************************************
|
|
;
|
|
; VSound_Client_Hook
|
|
;
|
|
; DESCRIPTION:
|
|
;
|
|
; This routine is called for every I/O access to our port. First,
|
|
; it checks to see if the VM issuing the I/O is the current owner.
|
|
; If not, it displays a dialog box so the user can decide what to
|
|
; do.
|
|
;
|
|
;*****************************************************************************
|
|
|
|
VSound_Identification:
|
|
Pop EAX
|
|
Push ECX
|
|
Mov ECX, VSound_StatePos
|
|
|
|
Mov AL, [VSound_ID+ECX]
|
|
Inc ECX
|
|
And ECX, 7
|
|
Mov VSound_StatePos, ECX
|
|
|
|
Pop ECX
|
|
Ret
|
|
|
|
VSound_GetServerString:
|
|
Pop EAX
|
|
Push ECX
|
|
Mov ECX, VSound_StatePos
|
|
|
|
Mov AL, [VSound_ServerString+ECX]
|
|
Inc ECX
|
|
And ECX, 63
|
|
Mov VSound_StatePos, ECX
|
|
|
|
Pop ECX
|
|
Ret
|
|
|
|
VSound_GetBufferUsed:
|
|
Pop EAX
|
|
Push ECX
|
|
Mov ECX, VSound_StatePos
|
|
|
|
Xor ECX, 1
|
|
Mov AL, [Byte Ptr VSound_BufferUsed+ECX]
|
|
Mov VSound_StatePos, ECX
|
|
|
|
Pop ECX
|
|
Ret
|
|
|
|
VSound_GetTSC:
|
|
Pop EAX
|
|
Push ECX
|
|
Mov ECX, VSound_StatePos
|
|
|
|
Mov AL, [Byte Ptr VSound_TimeStamp1+ECX]
|
|
Inc ECX
|
|
And ECX, 7
|
|
|
|
Mov VSound_StatePos, ECX
|
|
|
|
Pop ECX
|
|
Ret
|
|
|
|
VSound_Get0:
|
|
Xor AL, AL
|
|
|
|
Pop ECX
|
|
Ret
|
|
|
|
VSound_GetDebugValue:
|
|
Pop EAX
|
|
Push ECX
|
|
Mov ECX, VSound_StatePos
|
|
|
|
Mov AL, [Byte Ptr VSound_DebugValue+ECX]
|
|
Inc ECX
|
|
And ECX, 3
|
|
|
|
Mov VSound_StatePos, ECX
|
|
|
|
Pop ECX
|
|
Ret
|
|
|
|
BeginProc VSound_Client_Hook
|
|
|
|
;---------------------------------------------------------------------
|
|
; Resolve Contention
|
|
;---------------------------------------------------------------------
|
|
|
|
Push EAX
|
|
|
|
Mov EAX, VSound_Client
|
|
|
|
Cmp VSound_ServerValid, 0
|
|
JE NoValidServer
|
|
|
|
Cmp EAX, EBX ; Is the request from the
|
|
JE Process_IO ; current owner?
|
|
|
|
Test EAX, EAX ; Was there a previous owner?
|
|
JZ New_Owner
|
|
|
|
NoValidServer:
|
|
Pop EAX
|
|
|
|
Dispatch_Byte_IO Fall_Through, <SHORT Blocked_IO>
|
|
|
|
Mov AL, 80h
|
|
|
|
Blocked_IO:
|
|
Ret
|
|
|
|
New_Owner:
|
|
Mov VSound_Client, EBX
|
|
Mov VSound_ClientCallback, 0
|
|
|
|
Process_IO:
|
|
Pop EAX
|
|
|
|
Dispatch_Byte_IO Fall_Through, <SHORT VSound_Out>
|
|
|
|
Push EAX
|
|
Mov EAX, VSound_State
|
|
Cmp EAX, VSOUND_CLIENTSTATES
|
|
JAE VSound_Unknown
|
|
|
|
Jmp [VSound_InTable+EAX*4]
|
|
|
|
VSound_Unknown:
|
|
Pop EAX
|
|
Xor AL, AL
|
|
Ret
|
|
|
|
VSound_Out:
|
|
Push EAX
|
|
Mov Byte Ptr VSound_State, AL
|
|
And EAX, 0FFh
|
|
|
|
Cmp EAX, VSOUND_CLIENTSTATES
|
|
JAE VSound_Out_Nothing
|
|
|
|
Jmp [VSound_OutTable+EAX*4]
|
|
|
|
VSound_Out_GetTSC:
|
|
DB 0Fh
|
|
DB 31h ; RdTSC
|
|
Mov VSound_TimeStamp1, EAX
|
|
Mov VSound_TimeStamp2, EDX
|
|
Jmp VSound_Out_ResetStatePos
|
|
|
|
VSound_Out_GetBufferUsed:
|
|
Mov EAX, VSound_TailPointer
|
|
Sub EAX, VSound_HeadPointer
|
|
And EAX, VSOUND_BUFFERSIZE-1
|
|
Mov VSound_BufferUsed, EAX
|
|
|
|
VSound_Out_ResetStatePos:
|
|
Mov VSound_StatePos, 0
|
|
|
|
VSound_Out_Nothing:
|
|
Pop EAX
|
|
Ret
|
|
|
|
VSound_Out_ResetClient:
|
|
Xor EAX, EAX
|
|
Mov VSound_Client, EAX
|
|
Mov VSound_ClientCallback, EAX
|
|
|
|
Pop EAX
|
|
|
|
Ret
|
|
|
|
VSound_Out_SetCallbackAddress:
|
|
Mov AX, [EBP+CLIENT_REG_STRUC.CLIENT_CS]
|
|
ShL EAX, 16
|
|
Mov AX, [EBP+CLIENT_REG_STRUC.CLIENT_BX]
|
|
|
|
Mov VSound_ClientCallback, EAX
|
|
|
|
Pop EAX
|
|
Ret
|
|
|
|
EndProc VSound_Client_Hook
|
|
|
|
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
;--------------------------------------------------------------------
|
|
|
|
BeginProc VSound_Server_Hook
|
|
|
|
Push EAX
|
|
|
|
Mov EAX, VSound_Server
|
|
|
|
Cmp EAX, EBX ; Is the request from the
|
|
JE Process_Server_IO ; current owner?
|
|
|
|
Test EAX, EAX ; Was there a previous owner?
|
|
JZ New_Server
|
|
|
|
Pop EAX
|
|
|
|
Dispatch_Byte_IO Fall_Through, <SHORT Server_Blocked_IO>
|
|
|
|
Mov AL, 80h
|
|
|
|
Server_Blocked_IO:
|
|
Ret
|
|
|
|
New_Server:
|
|
Mov VSound_Server, EBX
|
|
|
|
Process_Server_IO:
|
|
Pop EAX
|
|
|
|
Dispatch_Byte_IO Fall_Through, <SHORT VSound_Server_Out>
|
|
|
|
Cmp VSound_ServerValid, 1
|
|
JE VSound_Server_Validated
|
|
|
|
Mov ECX, VSound_ServerInPos
|
|
Mov AL, [VSound_ServerID+ECX]
|
|
Inc ECX
|
|
And ECX, 7
|
|
Mov VSound_ServerInPos, ECX
|
|
Ret
|
|
|
|
VSound_Server_Validated:
|
|
Mov ECX, VSound_Client
|
|
Add ECX, 0FFFFFFFFh
|
|
SBB AL, AL ; Returns 0 if not connected, 0FFh if connected
|
|
Ret
|
|
|
|
VSound_Server_Out:
|
|
Test AL, AL ; Reset?
|
|
JZ VSound_Server_Reset
|
|
|
|
Mov ECX, VSound_ServerOutPos
|
|
|
|
Cmp VSound_ServerValid, 1
|
|
JE VSound_ReceiveServerString
|
|
|
|
Cmp [VSound_ServerID+ECX], AL
|
|
JE VSound_ValidByte
|
|
|
|
Mov VSound_ServerOutPos, 0
|
|
Ret
|
|
|
|
VSound_ValidByte:
|
|
Inc ECX
|
|
And ECX, 7
|
|
Mov VSound_ServerOutPos, ECX
|
|
JNZ VSound_ServerNotValidated
|
|
|
|
Mov VSound_ServerValid, 1
|
|
|
|
VSound_ServerNotValidated:
|
|
Ret
|
|
|
|
VSound_ReceiveServerString:
|
|
Mov [VSound_ServerString+ECX], AL
|
|
Inc ECX
|
|
And ECX, 63
|
|
Mov VSound_ServerOutPos, ECX
|
|
Ret
|
|
|
|
VSound_Server_Reset:
|
|
Xor ECX, ECX
|
|
Mov VSound_Server, ECX
|
|
Mov VSound_ServerValid, ECX
|
|
Mov VSound_ServerInPos, ECX
|
|
Mov VSound_ServerOutPos, ECX
|
|
|
|
Ret
|
|
|
|
EndProc VSound_Server_Hook
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
BeginProc VSound_Data_Hook
|
|
|
|
Cmp EBX, VSound_Server
|
|
JE VSound_Data_Server
|
|
|
|
Cmp EBX, VSound_Client
|
|
JE VSound_Data_Client
|
|
|
|
Ret
|
|
|
|
VSound_Data_Client:
|
|
Cmp CX, String_IO or Rep_IO or Byte_Output
|
|
JNE Data_Client_Simulate
|
|
|
|
PushAD
|
|
Push ES
|
|
PushF
|
|
|
|
ClI
|
|
|
|
Push DS
|
|
Pop ES
|
|
|
|
ShR ECX, 16 ; ECX = segment.
|
|
Mov EAX, [EBP+CLIENT_REG_STRUC.CLIENT_ECX]
|
|
|
|
ShL ECX, 4
|
|
Mov ESI, [EBP+CLIENT_REG_STRUC.CLIENT_ESI]
|
|
|
|
And ESI, 0FFFFh
|
|
Mov EDI, VSound_TailPointer
|
|
|
|
Add ESI, ECX ; ESI = data source.
|
|
And EAX, 0FFFFh ; EAX = byte count
|
|
|
|
Test EAX, 3 ; Must be multiple of 4 bytes
|
|
JNZ VSound_DataClientExit
|
|
|
|
LEA EDX, [EDI+EAX]
|
|
Add EDI, Offset VSound_Data
|
|
|
|
Cmp EDX, VSOUND_BUFFERSIZE
|
|
JB VSound_DataClient1
|
|
|
|
Mov ECX, VSOUND_BUFFERSIZE
|
|
LEA EAX, [EDX-VSOUND_BUFFERSIZE]
|
|
|
|
Sub ECX, VSound_TailPointer
|
|
ShR ECX, 2
|
|
|
|
Rep MovsD
|
|
|
|
Mov EDI, Offset VSound_Data
|
|
|
|
VSound_DataClient1:
|
|
ShR EAX, 2
|
|
And EDX, VSOUND_BUFFERSIZE-1
|
|
|
|
Mov ECX, EAX
|
|
Mov VSound_TailPointer, EDX
|
|
|
|
Rep MovsD
|
|
|
|
VSound_DataClientExit:
|
|
PopF
|
|
Pop ES
|
|
PopAD
|
|
|
|
Data_Client_Simulate:
|
|
Ret
|
|
|
|
VSound_Data_Server:
|
|
|
|
;
|
|
; The server will only receive data if:
|
|
; 1) A Rep InsB instruction is used. No other instruction will work
|
|
; 2) The ECX count is a multiple of 4
|
|
; 3) The ECX count must be less than BUFFERSIZE
|
|
|
|
Cmp CX, String_IO or Rep_IO or Addr_32_IO or Byte_Input
|
|
JNE Data_Server_Simulate
|
|
|
|
PushAD
|
|
Push ES
|
|
PushF
|
|
|
|
ClI
|
|
|
|
ShR ECX, 16
|
|
Mov ES, CX
|
|
|
|
Mov EAX, [EBP+CLIENT_REG_STRUC.CLIENT_ECX]
|
|
Mov EDI, [EBP+CLIENT_REG_STRUC.CLIENT_EDI]
|
|
|
|
Test EAX, 3
|
|
JNZ VSound_DataServerExit
|
|
|
|
Cmp EAX, VSOUND_BUFFERSIZE
|
|
JAE VSound_DataServerExit
|
|
|
|
; Want minimum of bytes available and bytes requested
|
|
Mov ESI, VSound_HeadPointer
|
|
Mov EBX, VSound_TailPointer
|
|
|
|
Sub EBX, ESI
|
|
And EBX, VSOUND_BUFFERSIZE-1 ; EBX = bytes available
|
|
; EAX = bytes requested
|
|
Cmp EBX, EAX
|
|
JB VSound_DataServer1
|
|
|
|
Mov EBX, EAX
|
|
|
|
VSound_DataServer1: ; EBX = bytes to transfer
|
|
Sub EAX, EBX ; EAX = bytes to zero
|
|
LEA EDX, [ESI+EBX]
|
|
|
|
ShR EBX, 2 ; EBX = dwords to transfer
|
|
Add ESI, Offset VSound_Data
|
|
|
|
Cmp EDX, VSOUND_BUFFERSIZE ; Does it span the buffer boundary?
|
|
JB VSound_DataServer2
|
|
|
|
LEA EBX, [EDX-VSOUND_BUFFERSIZE]
|
|
Mov ECX, VSOUND_BUFFERSIZE
|
|
|
|
ShR EBX, 2
|
|
Sub ECX, VSound_HeadPointer
|
|
|
|
ShR ECX, 2
|
|
|
|
Rep MovsD
|
|
|
|
Mov ESI, Offset VSound_Data
|
|
|
|
VSound_DataServer2:
|
|
ShR EAX, 2
|
|
Mov ECX, EBX
|
|
Rep MovsD
|
|
|
|
Mov ECX, EAX
|
|
And EDX, VSOUND_BUFFERSIZE-1
|
|
|
|
Xor EAX, EAX
|
|
Mov VSound_HeadPointer, EDX
|
|
|
|
Rep StosD
|
|
|
|
; ECX = 0
|
|
Mov EBX, VSound_Client
|
|
Cmp VSound_ClientCallback, ECX
|
|
JE VSound_DataServerExit
|
|
Test EBX, EBX
|
|
JZ VSound_DataServerExit
|
|
|
|
Mov EBP, [EBX+CB_S.CB_Client_Pointer]
|
|
|
|
VMMCall Set_Execution_Focus
|
|
JC VSound_DataServerExit
|
|
|
|
Push_Client_State
|
|
|
|
VMMCall Begin_Nest_V86_Exec
|
|
|
|
MovZX EDX, Word Ptr [VSound_ClientCallback]
|
|
MovZX ECX, Word Ptr [VSound_ClientCallback+2]
|
|
VMMCall Simulate_Far_Call
|
|
VMMCall Resume_Exec
|
|
|
|
VMMCall End_Nest_Exec
|
|
|
|
Pop_Client_State
|
|
|
|
VSound_DataServerExit:
|
|
PopF
|
|
Pop ES
|
|
PopAD
|
|
|
|
Data_Server_Simulate:
|
|
Ret
|
|
|
|
EndProc VSound_Data_Hook
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
VxD_CODE_ENDS
|
|
|
|
|
|
END
|