summaryrefslogtreecommitdiffstats
path: root/private/mvdm/sim16
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/sim16')
-rw-r--r--private/mvdm/sim16/incs.inc5
-rw-r--r--private/mvdm/sim16/makefile52
-rw-r--r--private/mvdm/sim16/segdefs.inc7
-rw-r--r--private/mvdm/sim16/sim16.asm907
-rw-r--r--private/mvdm/sim16/sim16.def19
-rw-r--r--private/mvdm/sim16/sim16.inc143
-rw-r--r--private/mvdm/sim16/sim16.mac59
-rw-r--r--private/mvdm/sim16/siminit.asm234
8 files changed, 1426 insertions, 0 deletions
diff --git a/private/mvdm/sim16/incs.inc b/private/mvdm/sim16/incs.inc
new file mode 100644
index 000000000..864a8b69b
--- /dev/null
+++ b/private/mvdm/sim16/incs.inc
@@ -0,0 +1,5 @@
+include segdefs.inc ; segment definitions
+include sim16.inc
+include sim16.mac
+
+.386
diff --git a/private/mvdm/sim16/makefile b/private/mvdm/sim16/makefile
new file mode 100644
index 000000000..c7e717548
--- /dev/null
+++ b/private/mvdm/sim16/makefile
@@ -0,0 +1,52 @@
+# SIM16 makefile
+# Initial version ??-Jan-91 by Chandan Chauhan
+#
+
+########## Path definition so we find 16 bit tools ##########
+# Also works around stupid bug in RC 3.1 that doesn't allow rcpp.err to be
+# in a directory that is greater than 128 chars down the path, even if
+# rc 3.1 is running as an OS/2 app.
+
+PATH = $(_NTBINDIR)\private\mvdm\tools16;$(PATH)
+
+.SUFFIXES:
+.SUFFIXES: .c .asm .h .inc .obj .lst .sys .exe .com .map .sym .def .lib
+
+
+NAME = sim16
+LIBS = ..\wow16\lib\libw ..\wow16\lib\mdllcew
+
+CC = cl16 -c -nologo -Asnw -G2sw -Zp -W2
+#ASM = masm -Mx -DSTACKSWITCH
+ASM = masm -Mx -t
+LINK = link16 /nod/noe/map/align:16
+
+.c.obj:
+ $(CC) $*.c
+
+.asm.obj:
+ $(ASM) $*;
+
+.map.sym:
+ mapsym $*
+
+.def.lib:
+ implib $*.lib $*.def
+
+goal: $(NAME).dll $(NAME).sym $(NAME).lib
+
+clean:
+ if exist *.obj del *.obj
+ if exist *.dll del *.dll
+ if exist *.map del *.map
+ if exist *.sym del *.sym
+ if exist *.lib del *.lib
+
+
+sim16.obj: sim16.asm sim16.inc sim16.mac incs.inc
+
+siminit.obj: siminit.asm sim16.inc sim16.mac incs.inc
+
+sim16.dll: sim16.obj siminit.obj sim16.def
+ $(LINK) sim16.obj siminit.obj,sim16.dll,sim16/map,$(LIBS),sim16.def;
+ rc16 $(NAME).dll
diff --git a/private/mvdm/sim16/segdefs.inc b/private/mvdm/sim16/segdefs.inc
new file mode 100644
index 000000000..127eed133
--- /dev/null
+++ b/private/mvdm/sim16/segdefs.inc
@@ -0,0 +1,7 @@
+MAIN_CODE SEGMENT WORD PUBLIC 'CODE'
+MAIN_CODE ENDS
+
+DGROUP GROUP MAIN_DATA
+
+MAIN_DATA SEGMENT WORD PUBLIC 'DATA'
+MAIN_DATA ENDS
diff --git a/private/mvdm/sim16/sim16.asm b/private/mvdm/sim16/sim16.asm
new file mode 100644
index 000000000..96cc61dc1
--- /dev/null
+++ b/private/mvdm/sim16/sim16.asm
@@ -0,0 +1,907 @@
+;******************************************************************************
+;
+; Simulator 16
+;
+; Author : Chandan Chauhan
+;
+; Date : 1/28/91
+;
+;******************************************************************************
+
+include incs.inc ; segment definitions
+
+
+MAXSIZE EQU 1024 ; 1k length
+
+Arg1 EQU [bp+6]
+Arg2 EQU [bp+8]
+
+WOW32_Buffer EQU [bp+6] ; buffer address
+WOW32_Size EQU [bp+8] ; length of VDM memory
+WOW32_Off EQU [bp+10] ; off of VDM memory
+WOW32_Sel EQU [bp+12] ; sel of VDM memory
+WOWStackNP EQU [bp+6] ; WOWStack
+WOWStackOff EQU [bp+6]
+WOWStackSel EQU [bp+8]
+
+ extrn Initialize:near
+
+MAIN_DATA SEGMENT
+ PUBLIC TransmitPkt, ReceivePkt, ReceivePktPtr, RespPkt, ToWOW32Pkt
+ PUBLIC ACKPkt, NAKPkt, GetMemPkt, SetMemPkt, WAKEUPPkt
+ PUBLIC fReceive, fRxCount, fRxError, RxPktLen
+ PUBLIC fTxCount, fTransmitting
+ PUBLIC fInitTime
+ PUBLIC VDMAddress
+ PUBLIC WOWStack, WOW32Buffer
+
+ Reserved DB 16 DUP (0) ; reserved
+
+ TransmitPkt DD -1 ; packet being transmitted
+ TransmitPktLen DW 0 ; packet being transmitted
+ TransmitPktPtr DW 0 ; byte to Tx
+
+ ReceivePkt DB MAXSIZE DUP (0FFh) ; packet being received
+ ReceivePktPtr DW 0 ; packet being received
+
+ RespPkt DB MAXSIZE DUP (0FFh) ; packet being transmitted
+
+ ToWOW32Pkt DB 9 DUP (?) ; ToWOW32 packet
+ DB 0
+
+ WAKEUPPkt DB 9 DUP (0) ; WAKEUP packet
+ DB 0
+
+ ACKPkt DB 5 DUP (?) ; ACK packet
+ DB 0
+
+ NAKPkt DB 5 DUP (?) ; NAK packet
+ DB 0
+
+ GetMemPkt DB MAXSIZE DUP (?) ;***************
+ SetMemPkt DB MAXSIZE DUP (?) ;***************
+
+
+ VDMAddress DD -1 ; stores VDM sel:off
+ VDMLength DW -1 ; number of bytes
+
+ WOW32Buffer DD -1 ; ptr caller's buffer
+ WOWStack DD -1 ; ptr to caller's WOWStack
+
+ fTxCount DW 0
+ fTransmitting DW 0
+
+ fReceive DW 0
+ fRxCount DW 0
+ fRxError DW 0
+
+ fInitTime DW 0
+ fInitDLL DW 0
+
+ RxPktLen DW 0
+
+ Stack DW 256 DUP (?)
+ StackTop DW ?
+ OldSS DW ?
+ OldSP DW ?
+ Scratch DW ?
+ fStackUse DW -1
+
+ IntRoutines LABEL WORD
+ DW COMISR_MSR
+ DW COMISR_Transmit
+ DW COMISR_Receive
+ DW COMISR_LSR
+
+ HelloString DB cr, lf, 'WOW Simulator *****', cr, lf, lf
+ DB 'Hello, this is a test string !!!!!!!!!!', cr, lf
+ HelloStringLen EQU $ - HelloString
+
+MAIN_DATA ENDS
+
+
+
+MAIN_CODE SEGMENT
+ ASSUME CS:MAIN_CODE, DS:MAIN_DATA, ES:NOTHING
+
+;*****************************************************************************
+; S I M U L A T O R L A Y E R
+;*****************************************************************************
+
+;*****************************************************************************
+;
+; Sim32SendSim16
+;
+;*****************************************************************************
+
+;***************
+
+PROCEDURE Sim32SendSim16 PUBLIC, FAR
+
+ push bp ; save stack frame
+ mov bp, sp
+
+ pusha ; temps...
+ push ds ; temps...
+ push es ; temps...
+
+ mov bx, ds
+
+ mov ax, SEG MAIN_DATA
+ mov ds, ax
+ mov si, OFFSET WAKEUPPkt ; DS:SI -> WAKEUP packet
+
+
+ mov ax, WOWStackNP
+ mov WOWStack._off, ax
+ mov WOWStack._sel, bx
+
+ cmp fInitTime, 0
+ je Sim32SendSim16_Init
+
+
+ les bx, WOWStack ; ES:BX -> SS:SP of WOW VDM task
+ mov ax, es:[bx]._off ; get SP
+ mov [si].MEM_OFF, ax
+ mov ax, es:[bx]._sel ; get SS
+ mov [si].MEM_SEL, ax
+
+ call Xceive
+
+Sim32SendSim16_Ret:
+ les bx, WOWStack ; ES:BX -> SS:SP of WOW VDM task
+ mov di, OFFSET ReceivePkt
+ mov ax, [di].ToWOW32_OFF
+ mov es:[bx]._off, ax
+ mov ax, [di].ToWOW32_SEL
+ mov es:[bx]._sel, ax
+
+
+ pop es ; temps...
+ pop ds ; temps...
+ popa ; temps...
+
+ mov sp, bp
+ pop bp
+
+ ret 2
+
+Sim32SendSim16_Init:
+ call Receive
+ inc fInitTime
+ call Initialize
+ jmp SHORT Sim32SendSim16_Ret
+
+
+Sim32SendSim16 ENDP
+
+
+;*****************************************************************************
+;
+; Sim32GetVDMMemory
+;
+;*****************************************************************************
+
+;***************
+
+PROCEDURE Sim32GetVDMMemory PUBLIC, FAR
+
+ push bp ; save stack frame
+ mov bp, sp
+
+ pusha ; temps...
+ push ds ; temps...
+ push es ; temps...
+
+ mov bx, ds
+
+ mov ax, SEG MAIN_DATA
+ mov ds, ax
+ mov si, OFFSET GetMemPkt ; DS:SI -> ToWOW32 packet
+
+ mov ax, WOW32_Buffer ; get buffer's address
+ mov WOW32Buffer._off, ax
+ mov ax, bx
+ mov WOW32Buffer._sel, ax
+
+ mov ax, WOW32_Off
+ mov [si].MEM_OFF, ax
+
+ mov ax, WOW32_Sel
+ mov [si].MEM_SEL, ax
+
+ mov cx, WOW32_Size ; get the length
+
+ cmp cx, 3B6h
+ jg Sim32GetMem_Error
+
+ mov [si].MEM_LENGTH, cx
+
+ call Xceive ; send GetMem packet and pickup
+ ; the response
+ mov cx, WOW32_Size
+
+ les di, WOW32Buffer ; ES:DI -> WOW32 buffer
+ mov si, OFFSET ReceivePkt+4
+
+ rep movsb
+
+ pop es ; temps...
+ pop ds ; temps...
+ popa ; temps...
+
+ mov sp, bp
+ pop bp
+
+ ret 8
+
+
+Sim32GetMem_Error:
+ int 3
+
+Sim32GetVDMMemory ENDP
+
+;*****************************************************************************
+;
+; Sim32SetVDMMemory
+;
+;*****************************************************************************
+
+;***************
+
+PROCEDURE Sim32SetVDMMemory PUBLIC, FAR
+
+ push bp ; save stack frame
+ mov bp, sp
+
+ pusha ; temps...
+ push ds ; temps...
+ push es ; temps...
+
+ mov bx, ds
+
+ mov ax, SEG MAIN_DATA
+ mov ds, ax
+ mov di, OFFSET SetMemPkt ; DS:DI -> SetMem packet
+
+ mov ax, WOW32_Buffer ; get buffer's address
+ mov WOW32Buffer._off, ax
+ mov ax, bx
+ mov WOW32Buffer._sel, ax
+
+ mov ax, WOW32_Off
+ mov [di].MEM_OFF, ax
+
+ mov ax, WOW32_Sel
+ mov [di].MEM_SEL, ax
+
+ mov cx, WOW32_Size
+
+ cmp cx, 3B6h
+ jg Sim32SetMem_Error
+
+ mov [di].MEM_LENGTH, cx
+ mov bx, 11
+ add bx, cx
+ mov [di].Len, bx
+ add di, 0Ah
+ mov bx, ds
+ mov es, bx
+
+ lds si, WOW32Buffer ; DS:SI -> Buffer
+ rep movsb
+ mov BYTE PTR es:[di], EOT
+
+ mov ds, bx
+ mov si, OFFSET SetMemPkt ; DS:SI -> SetMem packet
+
+ call Xceive
+
+ pop es ; temps...
+ pop ds ; temps...
+ popa ; temps...
+
+ mov sp, bp
+ pop bp
+
+ ret 8
+
+Sim32SetMem_Error:
+ int 3
+
+Sim32SetVDMMemory ENDP
+
+
+;*****************************************************************************
+;
+; Sim16SendSim32
+;
+;*****************************************************************************
+
+PROCEDURE Sim16SendSim32 PUBLIC, FAR
+
+ push bp ; save stack frame
+ mov bp, sp
+
+ pusha ; temps...
+ push ds ; temps...
+ push es ; temps...
+
+ mov bx, ds
+ mov ax, SEG MAIN_DATA
+ mov ds, ax
+ mov si, OFFSET ToWOW32Pkt ; DS:SI -> ToWOW32 packet
+
+ cmp fInitDLL, 0
+ jne @f
+
+ pusha
+ call Initialize
+ popa
+
+ inc fInitDLL
+
+@@:
+
+ ; prepare ToWOW32 packet
+
+ mov ax, WOWStackOff
+ mov [si].ToWOW32_OFF, ax ;
+ mov ax, WOWStackSel
+ mov [si].ToWOW32_SEL, ax ;
+
+ ; send it
+
+ call Xceive ; send ToWOW32 packet and pick up
+ ; the response
+
+Sim16SendSim32_Loop:
+
+ mov di, OFFSET Receivepkt
+ mov ax, [di].MEM_OFF ; get sel:off and length from
+ mov VDMAddress._off, ax ; packet
+ mov ax, [di].MEM_SEL
+ mov VDMAddress._sel, ax
+ mov ax, [di].MEM_LENGTH
+ mov VDMLength, ax
+
+
+Sim16SendSim32_GetMem:
+
+ cmp [di].Command, GETMEM
+ jne Sim16SendSim32_SetMem
+
+ call GetVDMMemory ; get vdm memory
+
+ call Xceive ; send response and get next packet
+
+ jmp SHORT Sim16SendSim32_Loop
+
+
+Sim16SendSim32_SetMem:
+
+ cmp [di].Command, SETMEM
+ jne Sim16SendSim32_PszLen
+
+ call SetVDMMemory ; get vdm memory
+
+ call Xceive ; send response and get next packet
+
+ jmp SHORT Sim16SendSim32_Loop
+
+
+Sim16SendSim32_PszLen:
+
+ cmp [di].Command, PSZ
+ jne Sim16SendSim32_WakeUp
+
+ call PszLen
+
+ call Xceive ; send response and get next packet
+
+ jmp SHORT Sim16SendSim32_Loop
+
+
+Sim16SendSim32_WakeUp:
+
+ cmp [di].Command, WAKEUP
+ jne Sim16SendSim32_Error
+
+
+Sim16SendSim32_Done:
+
+ pop es ; temps...
+ pop ds ; temps...
+ popa ; temps...
+
+ IFDEF STACKSWITCH
+ cli
+ mov sp, VDMAddress._off
+ mov ss, VDMAddress._sel ; could be a task switch !
+ sub sp, 8
+ sti
+ ENDIF
+
+ pop bp
+
+ ret 4
+
+Sim16SendSim32_Error:
+
+ int 3
+ mov si, OFFSET NAKPkt
+ call Xceive
+ jmp SHORT Sim16SendSim32_Loop
+
+Sim16SendSim32 ENDP
+
+
+;*****************************************************************************
+;
+; GetVDMMemory
+;
+;*****************************************************************************
+
+PROCEDURE GetVDMMemory, PUBLIC
+ ASSUME CS:MAIN_CODE, DS:DGROUP
+
+ push di
+ push es
+ push ds
+
+ mov ax, ds
+ mov es, ax
+
+ mov di, OFFSET RespPkt+4 ; ES:DI -> Response Packet
+
+ mov cx, VDMLength
+ lds si, VDMAddress ; DS:SI -> memory to get
+
+ rep movsb
+
+ pop ds
+ pop es
+ pop di
+
+ mov si, OFFSET RespPkt ; DS:SI -> Resp packet
+ mov ax, si
+
+ mov cx, VDMLength
+ add cx, 5
+ mov [si].Len, cx
+ add si, cx
+ dec si
+ mov [si], BYTE PTR EOT
+
+ mov si, ax ; DS:SI -> Resp packet
+
+ ret
+
+GetVDMMemory ENDP
+
+
+;*****************************************************************************
+;
+; SetVDMMemory
+;
+;*****************************************************************************
+
+PROCEDURE SetVDMMemory, PUBLIC
+ ASSUME CS:MAIN_CODE, DS:DGROUP
+
+ push di
+ push es
+
+ lea si, ReceivePkt.DataM ; DS:SI -> Data to set
+
+ mov cx, VDMLength
+ les di, VDMAddress ; DS:SI -> memory to set
+
+ rep movsb
+
+ mov si, OFFSET RespPkt ; DS:DI -> Response Packet
+
+ mov [si].Len, 7
+ mov [si].MEM_OFF, 0AAh
+ mov BYTE PTR [si].MEM_SEL, EOT
+
+ pop es
+ pop di
+
+ ret
+
+SetVDMMemory ENDP
+
+
+
+;*****************************************************************************
+;
+; PszLen
+;
+; This routine returns the length of the null terminated string
+; address specified by VDMAddress.
+;
+;*****************************************************************************
+
+PROCEDURE PszLen, PUBLIC
+ ASSUME CS:MAIN_CODE, DS:DGROUP
+
+ push di
+ push es
+
+ les di, VDMAddress ; ES:DI -> String
+ mov cx, 0FFFFh
+
+ sub ax, ax ; look for null
+ repne scasb
+ jnz PszLen_Notfound
+
+ xor cx, 0FFFFh ; CX = length of string
+ mov si, OFFSET RespPkt ; DS:DI -> Response Packet
+
+ mov [si].Len, 7
+ mov [si].MEM_OFF, cx
+ mov BYTE PTR [si].MEM_SEL, EOT
+
+ pop es
+ pop di
+
+ ret
+
+
+PszLen_Notfound:
+
+ int 3
+
+ pop es
+ pop di
+
+ ret
+
+
+PszLen ENDP
+
+
+
+
+;*****************************************************************************
+; T R A N S P O R T L A Y E R
+;*****************************************************************************
+
+
+;*****************************************************************************
+;
+; Xceive - TransCeive
+;
+; DS:SI -> Packet to be transmitted
+;
+;*****************************************************************************
+
+PROCEDURE Xceive, PUBLIC
+ ASSUME CS:MAIN_CODE, DS:DGROUP
+
+ mov RxPktLen, -1
+ mov ReceivePktPtr, 0
+ mov fReceive, 0
+ mov fRxCount, 0
+ mov fRxError, 0
+
+ call StartTransmitter
+
+Xceive_Loop:
+ cmp fReceive, 0
+ je Xceive_Loop
+
+ mov fReceive, 0
+
+ cmp fRxError, 0
+ jne Xceive_NAK
+
+ cmp ReceivePkt, SOH
+ jne Xceive_NAK
+
+ mov bx, ReceivePkt.Len
+ dec bx
+
+ cmp ReceivePkt.[bx], EOT
+ jne Xceive_NAK
+
+ xor ax, ax
+ ret
+
+Xceive_NAK:
+ cmp fRxCount, MAXCOUNT
+ jg Xceive_Error
+
+ inc fRxCount
+
+ mov si, OFFSET NAKPkt
+
+ jmp SHORT Xceive_Loop
+
+Xceive_Error:
+
+ int 3
+ mov ax, 1
+ ret
+
+Xceive ENDP
+
+
+;*****************************************************************************
+;
+; Receive
+;
+;*****************************************************************************
+
+PROCEDURE Receive, PUBLIC
+ ASSUME CS:MAIN_CODE, DS:DGROUP
+
+ mov RxPktLen, -1
+ mov ReceivePktPtr, 0
+ mov fReceive, 0
+ mov fRxCount, 0
+
+Receive_Loop:
+ cmp fReceive, 0
+ je Receive_Loop
+
+ mov fReceive, 0
+
+ cmp fRxError, 0
+ jne Receive_NAK
+
+ xor ax, ax
+ ret
+
+Receive_NAK:
+
+ cmp fRxCount, MAXCOUNT
+ jg Receive_Error
+
+ inc fRxCount
+
+ mov si, OFFSET NAKPkt
+
+ call StartTransmitter
+
+ jmp SHORT Receive
+
+Receive_Error:
+
+ int 3
+ mov ax, 1
+ ret
+
+Receive ENDP
+
+
+
+;*****************************************************************************
+; S E R I A L D R I V E R
+;*****************************************************************************
+
+
+;*****************************************************************************
+;
+; Start Transmitter
+;
+;*****************************************************************************
+
+PROCEDURE StartTransmitter, PUBLIC
+ ASSUME CS:MAIN_CODE, DS:DGROUP
+
+StartTransmitter_Loop:
+ cmp fTransmitting, 1
+ je StartTransmitter_Loop
+
+ mov TransmitPkt._sel, ds
+ mov TransmitPkt._off, si
+ mov ax, [si].Len ; get packet length
+ mov TransmitPktLen, ax
+ mov TransmitPktPtr, 0
+
+ mov fTransmitting, 1
+
+ cmp TransmitPktLen, 0
+ je StartTransmitter_Ret
+
+ mov dx, SERIALPORT ; COM1 or COM2
+ mov dl, IER ; turn on interrupts on 8250
+ in al, dx
+ DELAY
+
+ or al, TxInt
+ out dx, al
+ DELAY
+
+StartTransmitter_Ret:
+ ret
+
+StartTransmitter ENDP
+
+
+;*****************************************************************************
+;
+; Interrupt Routine
+;
+;*****************************************************************************
+
+PUBLIC COMISR, COMISR_LSR, COMISR_Receive, COMISR_Transmit, COMISR_MSR
+
+COMISR:
+ push ax
+ push ds
+
+ mov ax, SEG DGROUP
+ mov ds, ax
+
+ DISABLE
+
+ call NewStack
+
+ pusha
+ push es
+
+COMISR_More:
+ mov dx, SERIALPORT
+ mov dl, IIR
+ in al, dx
+ test al, IntPending ; is int pending ?
+ jnz COMISR_Ret ; no int is pending
+
+ xor ah, ah
+ mov di, ax
+ shr di, 1
+ add di, di
+ jmp [di].IntRoutines ; service int
+
+
+COMISR_LSR:
+ INT3
+ mov fRxError, 1
+ mov dx, SERIALPORT
+ mov dl, LSR
+ in al, dx
+ DELAY
+
+ jmp SHORT COMISR_More
+
+COMISR_Receive:
+ mov dx, SERIALPORT
+ in al, dx
+ DELAY
+
+ mov bx, ReceivePktPtr
+ mov [bx].ReceivePkt, al
+ inc ReceivePktPtr
+
+ cmp bx, 03
+ jne COMISR_ReceiveNext
+
+ mov ax, WORD PTR ReceivePkt+2
+ dec ax
+ mov RxPktLen, ax
+
+COMISR_ReceiveNext:
+ cmp bx, RxPktLen
+ jne @f
+
+ mov fReceive, 1 ; receive Done !
+@@:
+ jmp SHORT COMISR_More
+
+
+COMISR_Transmit:
+ cmp TransmitPktLen, 0
+ jne COMISR_Send
+
+ mov dx, SERIALPORT
+ mov dl, IER ; turn off interrupts on 8250
+ in al, dx
+ DELAY
+
+ and al, NOT TxInt
+ out dx, al
+ DELAY
+
+ mov fTransmitting, 0
+
+ jmp SHORT COMISR_More
+
+COMISR_Send:
+ les bx, DWORD PTR TransmitPkt
+ mov di, TransmitPktPtr
+ mov al, BYTE PTR es:[bx][di]
+ mov dx, SERIALPORT
+ out dx, al
+ DELAY
+ inc TransmitPktPtr
+ dec TransmitPktLen
+
+ jmp COMISR_More
+
+
+COMISR_MSR:
+ INT3
+ mov fRxError, 1
+ mov dx, SERIALPORT
+ mov dl, MSR
+ in al, dx
+ DELAY
+
+ jmp COMISR_More
+
+
+COMISR_Ret:
+ DELAY
+
+ pop es
+ popa
+
+ call OldStack
+
+ DISABLE
+
+ mov al, EOI
+ out PIC, al
+ pop ds
+ pop ax
+ iret
+
+
+;*****************************************************************************
+;
+; New Stack
+;
+;*****************************************************************************
+
+PROCEDURE NewStack, PUBLIC
+ ASSUME CS:MAIN_CODE, DS:DGROUP
+
+ inc fStackUse
+ jnz NewStack_Ret
+
+ pop Scratch
+ mov OldSS, ss
+ mov OldSP, sp
+ push ds
+ pop ss
+ mov sp, OFFSET StackTop
+ push Scratch
+
+NewStack_Ret:
+ ret
+
+NewStack ENDP
+
+
+;*****************************************************************************
+;
+; Old Stack
+;
+;*****************************************************************************
+
+PROCEDURE OldStack, PUBLIC
+ ASSUME CS:MAIN_CODE, DS:DGROUP
+
+ DISABLE
+ cmp fStackUse, 0
+ jne OldStack_Ret
+
+ pop Scratch
+ mov ss, OldSS
+ mov sp, OldSP
+ push Scratch
+
+OldStack_Ret:
+ dec fStackUse
+ ENABLE
+ ret
+
+OldStack ENDP
+
+
+MAIN_CODE ENDS
+
+ END
diff --git a/private/mvdm/sim16/sim16.def b/private/mvdm/sim16/sim16.def
new file mode 100644
index 000000000..4ce818143
--- /dev/null
+++ b/private/mvdm/sim16/sim16.def
@@ -0,0 +1,19 @@
+LIBRARY Sim16
+
+DESCRIPTION 'Sim16 - Simulator for WOW Project'
+
+EXETYPE WINDOWS
+
+STUB '..\WIN30LIB\WINSTUB.EXE'
+
+CODE PRELOAD FIXED
+
+DATA PRELOAD FIXED SINGLE
+
+HEAPSIZE 200
+
+EXPORTS WEP
+ Sim32SendSim16 @1
+ Sim32GetVDMMemory @2
+ Sim32SetVDMMemory @3
+ Sim16SendSim32 @4
diff --git a/private/mvdm/sim16/sim16.inc b/private/mvdm/sim16/sim16.inc
new file mode 100644
index 000000000..6c1e33ff8
--- /dev/null
+++ b/private/mvdm/sim16/sim16.inc
@@ -0,0 +1,143 @@
+;
+;
+; Serial driver for COM1 to be used by Sim16 layer.
+;
+;
+CharDev EQU 8000h
+StatusError EQU 8000h
+StatusBusy EQU 0200h
+StatusDone EQU 0100h
+ErrorGenF EQU 12
+
+;
+; PIC Addresses
+;
+
+PIC EQU 20h
+PIC_IntEnable EQU 21h
+EOI EQU 20h
+
+;
+; UART Port Addresses
+;
+
+SERIALPORT EQU 3F8h ; default serial port to be used, change this
+ ; to 2F8h if you want to use COM2.
+
+RxBuf EQU 0F8h ; base address
+Baud1 EQU RxBuf+1 ; baud divisor high byte
+IER EQU RxBuf+1 ; int. enable register
+IIR EQU RxBuf+2 ; int. identification register
+LCR EQU RxBuf+3 ;
+MCR EQU RxBuf+4 ;
+LSR EQU RxBuf+5 ;
+MSR EQU RxBuf+6 ;
+
+; UART Interrupt Identification Register Equates
+
+IntPending EQU 00000001b ; interrupt is pending
+
+; UART Line Control Register Equates
+
+DLAB EQU 10000000b ; divisor latch access bit
+SetBrk EQU 01000000b ; send break control bit
+StkParity EQU 00100000b ; stick parity control bit
+EvenParity EQU 00010000b ; even parity bit
+GenParity EQU 00001000b ; generate parity bit
+XStopBit EQU 00000100b ; extra stop bit
+WordLen8 EQU 00000011b ; word len = 8
+WordLen7 EQU 00000010b ; word len = 7
+WordLen6 EQU 00000001b ; word len = 6
+
+; UART Line Status Register Equates
+
+TransShReg EQU 01000000b ; tranmit shift register empty
+TransHReg EQU 00100000b ; transmit holding register empty
+BrkRcv EQU 00010000b ; break received
+FrameErr EQU 00001000b ; framing error
+ParityErr EQU 00000100b ; parity error
+OverRunErr EQU 00000010b ; overrun error
+RcvData EQU 00000001b ; received data ready
+
+RcvError EQU BrkRcv+FrameErr+ParityErr+OverRunErr
+
+; UART Modem Control Register Equates
+
+OUT1 EQU 00000100b ;
+OUT2 EQU 00001000b ; allow 8250 ints in
+SetRTS EQU 00000010b ; set RTS
+SetDTR EQU 00000001b ; set DTR
+
+
+; UART Modem Status Register Equates
+
+CD EQU 10000000b ; carrier detect
+RI EQU 01000000b ; ring indicator
+DSR EQU 00100000b ; data set ready
+CTS EQU 00010000b ; CTS
+CDC EQU 00001000b ; carrier dectect change
+RIC EQU 00000100b ; ring indicator change
+DSRC EQU 00000010b ; DSR change
+CTSC EQU 00000001b ; CTS change
+
+; UART Interrupt Enable Register Equates
+
+RxInt EQU 00000001b ; receive interrupt
+TxInt EQU 00000010b ; transmit interrupt
+LSInt EQU 00000100b ; line status interrupt
+MSInt EQU 00001000b ; modem status interrupt
+AllInt EQU RxInt+LSInt+MSInt
+
+CR EQU 0dh
+LF EQU 0ah
+EOM EQU '$'
+
+
+INT21 = 21h
+DISPLAY_FUNCTION = 9h
+DOS_OPEN = 3Dh
+DOS_CLOSE = 3Eh
+DOS_DONE = 0100h
+DOS_SUCCESS = 0h
+DOS_ERROR = 8000h
+DOS_GENFAIL = 0Ch
+EXPR_TYPE_SEG equ 0001b ; address type segment:offset
+OPEN_FLAG = 40h
+
+InitLCR EQU 03h ; initial LCR settings
+InitMCR EQU OUT2+SetRTS+SetDTR ; initial MCR settings
+BaudRate EQU 12 ; set it to 9600 BPS
+
+SOH EQU 1 ; start of header
+EOT EQU 4 ; end of transmission
+ToWOW32 EQU 1
+GETMEM EQU 2
+SETMEM EQU 3
+WAKEUP EQU 4
+RESP EQU 5
+ACK EQU 6
+NAK EQU 7
+PSZ EQU 8
+
+MAXCOUNT EQU 10
+
+Packet1 STRUC
+ Start DB ?
+ Command DB ?
+ Len DW ?
+ ToWOW32_OFF DW ?
+ ToWOW32_SEL DW ?
+Packet1 ENDS
+
+Packet2 STRUC
+ DD ?
+ MEM_OFF DW ?
+ MEM_SEL DW ?
+ MEM_LENGTH DW ?
+ DataM DB ?
+Packet2 ENDS
+
+junk1 STRUC
+ _off DW ?
+ _sel DW ?
+junk1 ENDS
diff --git a/private/mvdm/sim16/sim16.mac b/private/mvdm/sim16/sim16.mac
new file mode 100644
index 000000000..1543f894b
--- /dev/null
+++ b/private/mvdm/sim16/sim16.mac
@@ -0,0 +1,59 @@
+PROCEDURE MACRO name, p1, p2
+ align 4
+ IFB <p2>
+ name PROC
+ ELSE
+ name PROC FAR
+ ENDIF
+ IFNB <p1>
+ PUBLIC name
+ ENDIF
+ ENDM
+
+
+DELAY MACRO
+ clc
+ jnc $+2
+ ENDM
+
+DISABLE MACRO
+ cli
+ ENDM
+
+ENABLE MACRO
+ sti
+ ENDM
+
+
+SWAP_ESDS MACRO
+ push ds
+ push es
+ pop ds
+ pop es
+ ENDM
+
+SAVE_ENV MACRO
+ push si
+ push di
+ push ds
+ push es
+ ENDM
+
+RESTORE_ENV MACRO
+ pop es
+ pop ds
+ pop di
+ pop si
+ ENDM
+
+INT3 MACRO
+ int 3
+ ENDM
+
+
+MSG MACRO msg, strng
+ PUBLIC msg
+
+msg DB strng
+ DB cr, lf, eom
+ ENDM
diff --git a/private/mvdm/sim16/siminit.asm b/private/mvdm/sim16/siminit.asm
new file mode 100644
index 000000000..ba2e3c45f
--- /dev/null
+++ b/private/mvdm/sim16/siminit.asm
@@ -0,0 +1,234 @@
+include incs.inc
+
+ extrn LocalInit:FAR
+
+ extrn __acrtused:abs ; pull in windows startup code
+
+MAIN_DATA SEGMENT
+ extrn RespPkt:BYTE
+ extrn ToWOW32Pkt:BYTE
+ extrn WAKEUPPkt:BYTE
+ extrn ACKPkt:BYTE
+ extrn NAKPkt:BYTE
+ extrn GetMemPkt:BYTE
+ extrn SetMemPkt:BYTE
+MAIN_DATA ENDS
+
+
+MAIN_CODE SEGMENT
+ ASSUME CS:MAIN_CODE, DS:MAIN_DATA
+
+ extrn COMISR:NEAR
+
+;*****************************************************************************
+;
+; LibEntry, called when DLL is loaded
+;
+;*****************************************************************************
+
+ PUBLIC LibEntry
+LibEntry PROC FAR
+
+ int 3
+
+ jcxz LibEntry_Initialize
+
+ push ds ; heap segment
+ xor ax, ax ;
+ push ax
+ push cx ; heap size
+ call LocalInit ; initialize heap
+ or ax, ax
+ jz LibEntry_Fail
+
+LibEntry_Initialize:
+ call Initialize ; initialize com port and buffers
+
+LibEntry_Fail:
+ ret
+
+LibEntry ENDP
+
+
+;*****************************************************************************
+;
+; Initialize com port and memory
+;
+;*****************************************************************************
+
+ PUBLIC Initialize
+Initialize PROC NEAR
+
+ call Init_Com ; initialize com port
+ or ax, ax
+ jz Initialize_Fail
+
+ push ax
+ call Init_Mem ; initialize memory
+ pop ax
+
+ ret
+
+Initialize_Fail:
+ int 3
+ ret
+
+Initialize ENDP
+
+;*****************************************************************************
+;
+; WEP, called when DLL is unloaded
+;
+;*****************************************************************************
+
+ PUBLIC WEP
+
+WEP PROC FAR
+
+ nop
+ ret
+
+WEP ENDP
+
+;*****************************************************************************
+;
+; Initialization of the Port
+;
+;*****************************************************************************
+
+Init_Com PROC NEAR
+
+ mov dx, SERIALPORT
+ mov dl, LCR
+ mov al, DLAB ; turn on divisor latch
+ out dx, al
+ DELAY
+
+ mov dl, RxBuf
+ mov ax, BaudRate ; set baud rate
+ out dx, al
+ DELAY
+
+ inc dx
+ mov al, ah
+ out dx, al
+ DELAY
+
+ mov dl, LCR ; set LCR
+ mov al, InitLCR
+ out dx, al
+ DELAY
+
+ mov dl, IER ; turn on interrupts on 8250
+ mov al, AllInt
+ out dx, al
+ DELAY
+
+ mov dl, MCR ; set MCR
+ mov al, InitMCR
+ out dx, al
+
+Init_ClearRegisters:
+ mov dl, LSR
+ in al, dx
+ mov dl, RxBuf
+ in al, dx
+ mov dl, MSR
+ in al, dx
+ mov dl, IIR
+ in al, dx
+ in al, dx
+ test al, 1
+ jz Init_ClearRegisters
+
+ ;
+ ; install interrupt handler
+ ;
+
+ cli
+ mov al, 0Ch
+ push ds
+ mov dx, SEG MAIN_CODE
+ mov ds, dx
+ mov dx, OFFSET COMISR
+ mov ah, 25h
+ int 21h
+ pop ds
+
+ in al, PIC_IntEnable
+ and al, 0E7h
+ DELAY
+
+ out PIC_IntEnable, al
+ sti
+
+ mov al, EOI
+ out PIC, al
+
+ mov ax, 1 ; return sucess !
+
+ ret
+
+Init_Com ENDP
+
+
+;*****************************************************************************
+;
+; Initialize memory ie, allocate buffers and packets
+;
+;*****************************************************************************
+
+ PUBLIC Init_Mem
+
+Init_Mem PROC NEAR
+
+ mov bx, OFFSET RespPkt
+ mov [bx].Start, SOH ; start of header
+ mov [bx].Command, RESP ; Resp packet
+
+ mov bx, OFFSET ToWOW32Pkt ; ToWOW32 packet
+ mov [bx].Start, SOH ; start of header
+ mov [bx].Command, ToWOW32 ; ToWOW32 packet
+ mov [bx].Len, 9 ; length of entire packet
+ mov BYTE PTR [bx+8], EOT ; end of transmission
+
+ mov bx, OFFSET WAKEUPPkt ; WAKEUP packet
+ mov [bx].Start, SOH ; start of header
+ mov [bx].Command, WAKEUP ; WAKEUP packet
+ mov [bx].Len, 9 ; length of entire packet
+ mov BYTE PTR [bx+8], EOT ; end of transmission
+
+ mov bx, OFFSET ACKPkt ; ACK packet
+ mov [bx].Start, SOH ; start of header
+ mov [bx].Command, ACK ; ACK packet
+ mov [bx].Len, 5 ; length of entire packet
+ mov BYTE PTR [bx+4], EOT ; end of transmission
+
+ mov bx, OFFSET NAKPkt ; NAK packet
+ mov [bx].Start, SOH ; start of header
+ mov [bx].Command, NAK ; NAK packet
+ mov [bx].Len, 5 ; length of entire packet
+ mov BYTE PTR [bx+4], EOT ; end of transmission
+
+ mov bx, OFFSET GetMemPkt ; GetMem packet
+ mov [bx].Start, SOH ; start of header
+ mov [bx].Command, GETMEM ; GETMEN packet
+ mov [bx].Len, 11 ; length of entire packet
+ mov BYTE PTR [bx+10], EOT ; end of transmission
+
+ mov bx, OFFSET SetMemPkt ; SetMem packet
+ mov [bx].Start, SOH ; start of header
+ mov [bx].Command, SETMEM ; SETMEM packet
+ mov [bx].Len, 11 ; length of entire packet
+ mov BYTE PTR [bx+10], EOT ; end of transmission
+
+
+ ret
+
+Init_Mem ENDP
+
+
+MAIN_CODE ENDS
+
+
+ END LibEntry