;**************************************************************************
;                   IBM Sample Virtual  Device Driver
;
;                   Copyright  IBM Corp 1992.
;***************************************************************************
;Initial Release
;
; DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
; sample code created by IBM Corporation. This sample code is not
; part of any standard or IBM product and is provided to you solely
; for  the purpose of assisting you in the development of your
; applications.  The code is provided "AS IS", without
; warranty of any kind.  IBM shall not be liable for any damages
; arising out of your use of the sample code, even if they have been
; advised of the possibility of   such damages.
;
;
;
;        TITLE   vdft.asm
;        Purpose Initialize the 3270 dft adapter card.
;
;        These routines comprise the Virtual DFT device driver which
;        supports the 3270 adapter card.
;
;        These routines work in conjunction with the pdd.sys device driver.
;        The pdd.sys must be installed first for this driver to load
;        successfully.
;

        .386P

        OPTION  OLDMACROS
;       INCL_NONE  EQU     1
        INCL_VDH   EQU     1
        INCLUDE  mvdm.inc
        INCLUDE  basemid.inc
        INCLUDE  vdftp.inc
        ASSUME   CS: CSEG, DS:FLAT, SS: FLAT, ES: FLAT

PUBLIC  _VDDINIT
PUBLIC  PDFTPDDPROC

;
;                      Global data area  for vdft
;
;
DSEG            SEGMENT  DWORD USE32 PUBLIC 'DATA'
PszPddName      DB      'PDD.SYS',00H       ;the physical device driver name
PDFTPDDPROC     DF      0H                  ;pointer to use for the pdd entry
HIRQ_DFT        DD      0H                  ;handle for eoi hook

MAPSOURCE        DD       0A000H             ;
                 DD       0H
MapTarget        DD       0A000H              ;linear buffer address
                 DD       2H                 ;number  of pages
                 DD       0H                 ;handle for target


HTable     DD      VdftDaIn                    ;io hook table
           DD      VdftDaOut                   ;byte input handler
           DD       0H                         ;byte output handler
           DD       0H                         ;word input handler
           DD       0H                         ;word output handler

HTable_St  DD      VdftStIn                    ;byte input handler
           DD      VdftStOut                   ;byte output handler
           DD       0H                         ;word input handler
           DD       0H                         ;word output handler
           DD       0H                         ;dword & string I/O handler

Status_Byte               DD       ?          ;Status register value
HVDM_OWNER                DD       0H         ;handle to the vdm owner
InterruptsNotEnabled      DD       1H         ;Start with interrupts not enable
WAIT_FOR_EOI              DD       0H         ;EOI not done yet
WAIT_FOR_STATUS_OUT       DD       0H         ;out to status port
PDB_OWNER                 DW       0H
BUF_ADDRESS               DD       0A000H      ;linear address to map
                                              ;stay under one meg
                                              ; + 64k
                                              ;typically use the address
                                              ;of the shared memory
                                              ;buffer on the card to
                                              ;access

HVDM_CURRENT              DD       ?          ;Current vdm handle
PDB_CURRENT               DW       ?          ;Current pdb

DSEG       ENDS
;Currently this sample uses all global data
;This is a design issue the vdd writer must
;decide for the target driver,i.e. set up
;discardable data that is only used at init time,
;set the segment to be swappable,et al.
;See the vdd.def file for the currently supported
;definitions
;-dwk
;
;CSWAP_DATA  SEGMENT  DWORD USE32 PUBLIC 'CODE'
;HVDM_CURRENT              DD       ?          ;Current vdm handle
;PDB_CURRENT               DW       ?          ;Current pdb

;CSWAP_DATA  ENDS

;********************************************************************
;
; SUBROUTINE NAME:VdftDaIn
;
; DESCRIPTIVE NAME:
;
; FUNCTION: The function of this routine is to service the VDM
;           in instruction for dft in the IN to the data port
;           is the first occurrence of I/O. If it is not the
;           first occurrence then the hook for this port will have
;           been disabled. This routine requests I/O direct mode
;           and if successful does the IN instruction.
; ENTRY POINT:
; LINKAGE    : CALL NEAR
;
; INPUT:       portaddr       ebp + 8     port address to write to
;              pcrf           ebp + 4     pointer to client register frame
;
; EXIT-NORMAL:  al = byte  read in
;
; EXIT-ERROR:   al = 0    no byte read in
;
; INTERNAL REFERENCES:  NONE
;
; EXTERNAL REFERENCES:  NONE
;
;********************************************************************
;CSWAP_TEXT  SEGMENT  DWORD USE32 PUBLIC 'CODE'
CSEG   SEGMENT  DWORD USE32 PUBLIC 'CODE'
VdftDaIn         PROC NEAR

       push    ebp
       mov     ebp, esp
       align   4
       sub     esp, 4                             ;set up a byte to return
                                                  ;dataread

       mov     BYTE PTR [ebp-4], 0
       call    REQUESTDIRECT
       or      eax, eax
       je      VdftDaError

       push    HVDM_CURRENT
       push    FIRSTREG
       push    NUMPORTS
       push    OFFSET FLAT:HTABLE                 ;let vdh services know
       push    FALSE                              ;about our table entries
       call    VDHSETIOHOOKSTATE

       mov     dx, WORD PTR [ebp+12]
       in      al,dx
       mov     BYTE PTR [ebp-4], al
VdftDaSuccess:
       mov     al, BYTE PTR [ebp-4]
VdftDaError:
       leave
       ret     8
VdftDaIn        ENDP
;CSWAP_TEXT  ENDS
;********************************************************************
;
; SUBROUTINE NAME:VdftDaOut
;
; DESCRIPTIVE NAME:
;
; FUNCTION:  The function of this routine is to service the VDM
;            OUT instruction for DFT if the OUT to the data port
;            is the first occurence of I/O. If is no the first
;            occurence then the hook for this port will have
;            been disabled. This routine requests I/O direct
;            mode and if successful does the OUT instruction.
;              (PARAMETERS)  (passed on the stack)
;            ebp + 16         chartowrite - data to write
;            ebp + 12         portaddr    - port address
;            ebp + 8          pcrf        - client register frame pointer
;
; LINKAGE    : CALL NEAR
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = NONE
;
; EXIT-ERROR:  EAX = NONE
;
;********************************************************************
;CSEG   SEGMENT  DWORD USE32 PUBLIC 'CODE'
VdftDaOut       PROC NEAR
       push    ebp
       mov     ebp, esp
       call    REQUESTDIRECT
       or      eax, eax
       je      VDftDaOutError                     ;error out

       push    HVDM_CURRENT
       push    FIRSTREG
       push    NUMPORTS
       push    OFFSET FLAT:HTABLE                 ;pass our hook table
       push    FALSE
       call    VDHSETIOHOOKSTATE

       movzx   ax, BYTE PTR [ebp+16]
       mov     dx, WORD PTR [ebp+12]
VdftDaOutSuccess :
       out     dx, al
VdftDaOutError :
       leave
       ret     12
VdftDaOut       ENDP

;********************************************************************
;
; SUBROUTINE NAME:VdftStIn
;
; DESCRIPTIVE NAME:
;
; FUNCTION:        The function of this routine is to service the VDM
;                  IN instruction for DFT if the IN to the status port
;                  is the first occurrence of I/O. If it is not the
;                  first occurrence then the hook for this port will
;                  have been disabled. This routine requests I/O direct
;                  mode and if successful does the IN instruction.
;                  (PARAMETERS)  (passed on the stack)
;                  ebp + 12   portaddr          port to read from
;                  ebp + 8    pcrf              not currently used
; LINKAGE    : CALL NEAR
;
; INPUT: NONE
;
; EXIT-NORMAL: al  = 0    no byte read  in
;
; EXIT-ERROR:  al  = byte that was read in
;
;********************************************************************
VdftStIn        PROC NEAR
       push    ebp
       mov     ebp, esp
       align   4
       sub     esp, 4
                                                  ;set up for byte to read

       mov     BYTE PTR [ebp-4], 0
       call    REQUESTDIRECT
       or      eax, eax
       je      VDftInError
       cmp     WAIT_FOR_STATUS_OUT, 0

       je      VDftInError
       mov     al, BYTE PTR STATUS_BYTE
       jmp     VDftInError
       mov     dx, WORD PTR [ebp+12]
       in      al,dx

       mov     BYTE PTR [ebp-4], al
       mov     al, BYTE PTR [ebp-4]
VDftInError :
       leave
       ret     8

VdftStIn        ENDP

;********************************************************************
;
; SUBROUTINE NAME: VdftStOut
;
; DESCRIPTIVE NAME: Dft Status Port Out Instruction Handler.
;
; FUNCTION:         The function of this routine is to service the vdm OUT
;                   instruction of DFT if the out to the status port is the
;                   first I/O. If if is not the first occurence,then
;                   the hook for this port will have been disabled. This
;                   routine request I/O direct mode and if successful,does
;                   the OUT instruction.
;
; LINKAGE    : CALL NEAR
;
;
; Method     : (PARAMETERS passed on the stack )
;              ebp + 16  chartowrite   - the byte to write
;              ebp + 12  portaddr      - the port to write to
;              ebp + 8   pcrf          - client register frame pointer
;
;
; EXIT-NORMAL: EAX = NONE
;
; EXIT-ERROR:  EAX = NONE
;
;********************************************************************
VdftStOut       PROC NEAR
       push    ebp
       mov     ebp, esp
       call    RequestDirect
       or      eax, eax                                ;any error
       je      StOutError
       cmp     WAIT_FOR_STATUS_OUT, 0
       je      StOutError
       mov     WAIT_FOR_STATUS_OUT, 0
       je      StOutError
       movzx   ax, BYTE PTR [ebp+16]
       mov     dx, WORD PTR [ebp+12]
       out     dx, al

       cli                                             ;clear interrupts
       cmp     INTERRUPTSNOTENABLED, 0
       je      StOutError
       mov     eax, WAIT_FOR_EOI
       cmp     WAIT_FOR_STATUS_OUT, eax
       jne     StOutError
       call    EnableInterrupts                        ;enable interrupts in
                                                       ;the pdd
       sti                                             ;globally restore
                                                       ;interrupts
StOutError:
        leave
        ret     12
VdftStOut       ENDP

;********************************************************************
;
; SUBROUTINE NAME:VDFTCreate
;
; DESCRIPTIVE NAME:
;
; FUNCTION:       The function of this routine is to service the creation of
;                 a new vdm. I/O hooks will be installed for the dft port.
;
; Method          :Parameter are passed on the stack
;                  ebp + 8     hvdm
;                  ebp + 12    vdftpdb
;
;
;
; ENTRY POINT:
; LINKAGE    : CALL NEAR
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = 1                ; Successfully registered
;
; EXIT-ERROR:  EAX = 0                ; Error in registering
;
; INTERNAL REFERENCES:  NONE
;
; EXTERNAL REFERENCES:  NONE
;
;********************************************************************
VdftCreate      PROC NEAR
;      int     3                              ;
                                              ;this code will get called
                                              ;everytime we go into
                                              ;a dos session
                                              ;
       push    ebp
       mov     ebp, esp
       mov     eax, [ebp+8]                   ;set HVDM to
       mov     HVDM_CURRENT, eax              ;to current hvdm
       push    eax
       push    BUF_ADDRESS
       push    2                              ;number of pages

       push    OFFSET FLAT:VDFTFAULTHANDLER
       push    FALSE
       call    VDHINSTALLFAULTHOOK

       or      eax, eax
       je      VdftCreateError                     ;hook the 3270 status port
       push    HVDM_CURRENT                        ;if the hook is successful
       push    StatusReg                           ;terminate the vdm.
       push    NumStat
       push    OFFSET FLAT:HTABLE_ST
       push    VDHIIH_ALWAYS_TRAP
       call    VDHINSTALLIOHOOK

       or      eax, eax                            ;set up to install the
       je      VdftCreateError                     ;io hook
       push    HVDM_CURRENT
       push    FIRSTREG
       push    NUMPORTS
       push    OFFSET FLAT:HTABLE
       push    0
       call    VDHINSTALLIOHOOK

       or      eax, eax
       je      VdftCreateError
       sub eax, eax
VdftCreateSuccess:
VdftCreateError  :
       mov     eax, TRUE
       leave
       ret     8
VdftCreate      ENDP

;********************************************************************
;
; SUBROUTINE NAME: VDFTTerminate
;
; FUNCTION:          The function of this routine is to service the vdm
;                    termination. If the current VDM is the owner of the DFT
;                    port,clear the exclusive flag and saved hvdm of current.
;
; LINKAGE    : CALL NEAR
; METHOD     :       Parameters are passed on the stack
;                    ebp + 8  hvdm           handle to the vdm
;
;
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = NONE
;
; EXIT-ERROR:  EAX = NONE
;
; INTERNAL REFERENCES:  NONE
;
; EXTERNAL REFERENCES:  NONE
;
;********************************************************************
VdftTerminate   PROC NEAR
                                                   ;routine is called
;      int     3                                   ;every time a dos
       push    ebp                                 ;session is
       mov     ebp, esp                            ;terminated
       push    ebx                                 ;Save registers
       push    edi                                 ;for vdm
       push    esi

       mov     HVDM_OWNER, 0                       ;if we have n't
       cmp     INTERRUPTSNOTENABLED, 0             ; enable interrupts
       jne     VdftTermError                       ; say goodbye
       call    DISABLEINTERRUPTS                   ;tell the pdd
                                                   ;to disable interrupts

       mov     WAIT_FOR_STATUS_OUT, 0
       mov     WAIT_FOR_EOI, 0
       mov     STATUS_BYTE, 0
       push    HVDM_CURRENT
       push    FIRSTREG
       push    NUMPORTS
       push    OFFSET FLAT:HTABLE
       call    VDHREMOVEIOHOOK                     ;kill io hooks

       push    HVDM_CURRENT
       push    STATUSREG
       push    NUMSTAT
       push    OFFSET FLAT:HTABLE_ST
       call    VDHREMOVEIOHOOK

       push    OFFSET FLAT:MAPSOURCE               ;mark all pages as
       push    OFFSET FLAT:MAPTARGET               ;invalid
       push    VDHMT_INVALID
       call    VDHMAPPAGES


       push    HVDM_CURRENT                        ;remove our
       push    BUF_ADDRESS                         ;fault handler
       push    2                                   ;number of pages
       push    OFFSET FLAT:VDFTFAULTHANDLER
       call    VDHREMOVEFAULTHOOK
       sub eax,eax

VdftTermSuccess:                                   ;always return
VdftTermError:                                     ;Success to the vdm
       mov     eax, 1                              ;manager

VdftTermReturn :
        pop     esi
        pop     edi
        pop     ebx
        pop     ebp
        ret     4                                 ;clear the hvdm
                                                  ;off the stack
VdftTerminate   ENDP

;********************************************************************
;
; SUBROUTINE NAME:VdftFaultHandler.
;
; DESCRIPTIVE NAME: The function of this routine is to service the page
;                   fault handler entry point. This routine tries to get
;                   access to the adapter mapped into this VDM.
;
; FUNCTION:
;                   ebp + 8  pvdm      not currently used.
;
;
;
;
; ENTRY POINT:
; LINKAGE    : CALL NEAR
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = NONE
;
; EXIT-ERROR:  EAX = NONE
;********************************************************************
VdftFaultHandler        PROC NEAR
        call    REQUESTDIRECT
        ret     8
VdftFaultHandler        ENDP

;********************************************************************
;
; SUBROUTINE NAME:VdftPdbChange
;
; DESCRIPTIVE NAME:Dft routine called to register a PDB change handler
;                  entry point.
; FUNCTION:   The function of this routine is to register a PDB change
;             handler entry point. VDM task time context.
;
;
; LINKAGE    : CALL NEAR 32
;
; INPUT:       parameters passed on the stack
;              ebp    + 12    HVDM hvdm         not currently used
;              ebp    +  8    VDPTPDB segPDB
;
;
; EXIT-NORMAL: EAX = TRUE
;
; EXIT-ERROR:  NONE
;********************************************************************
VdftPdbChange   PROC NEAR
       push    ebp
       mov     ebp, esp

       mov     ax, WORD PTR [ebp+8]
       mov     PDB_CURRENT, ax
       mov     eax, 1
       leave
       ret     8
VdftPdbChange   ENDP

;********************************************************************
;
; SUBROUTINE NAME: VDFTPDBDestroy
;
; FUNCTION:        The function of this routine is to service the PDB
;                  destruction handler entry point. If the PDB has been
;                  destroyed, and the current PDB was the owner of the
;                  DFT port,cler the exclusive use flag and saved PDB
;                  address.
;
; Usage   :        DFT routine called at PDB destruction handler entry
;                  point.
;
;                  ebp + 12    HVDM  hvdm
;                  ebp + 8     SEG   segPDB
;
;
;
; ENTRY POINT:
; LINKAGE    : CALL NEAR
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = NONE
;
; EXIT-ERROR:  EAX = NONE
;
; INTERNAL REFERENCES:  NONE
;
; EXTERNAL REFERENCES:  NONE
;
;********************************************************************
VdftPdbDestroy  PROC NEAR
       push    ebp
       mov     ebp, esp

       mov     eax, HVDM_OWNER
       cmp     DWORD PTR [ebp+12], eax
       jne     VdftPdbDestroyError
       mov     ax, PDB_OWNER
       cmp     WORD PTR [ebp+8], ax
       jne     VdftPdbDestroyError
       mov     HVDM_OWNER, 0

       mov     PDB_OWNER, WORD PTR 0

       cmp     INTERRUPTSNOTENABLED, 0
       jne     VdftPdbDestroyError


       call    DISABLEINTERRUPTS



       mov     WAIT_FOR_STATUS_OUT, 0

       mov     WAIT_FOR_EOI, 0

       mov     STATUS_BYTE, 0

       push    OFFSET FLAT:MAPSOURCE
       push    OFFSET FLAT:MAPTARGET
       push    1
       call    VDHMAPPAGES

VdftPdbDestroyOk:
       mov     eax, TRUE
VdftPdbDestroyError:
       leave
       ret     8

VdftPdbDestroy  ENDP

;********************************************************************
;
; SUBROUTINE NAME:  RequestDirect
;
; FUNCTION: The function of this routine is to  service the IN/OUT trap.
;            On the first I/O to the port,the current owner of the
;            port is determined. If if is not the current requestor,
;            the current requestor will be denied. In the case of a
;            vdm the vdm will be terminated.
;
; Usage      Internal routine which will determine if the current
;            requestor is the current owner of the port.
;
;
;
;
; ENTRY POINT:
; LINKAGE    : CALL NEAR 32
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = NONE
;
; EXIT-ERROR:  EAX = NONE
;
; INTERNAL REFERENCES:  NONE
;
; EXTERNAL REFERENCES:  NONE
;
;********************************************************************
RequestDirect   PROC NEAR
       push    ebp
       mov     ebp, esp
       sub     esp, 4                                 ;allocate for our
                                                      ;response value;
                                                      ;
       mov     eax, HVDM_CURRENT
       cmp     HVDM_OWNER, eax
       je      RequestError
       cmp     HVDM_OWNER, 0
       je      RequestError
       push    0
       push    0
       push    MSG_VLPT_DEVICE_BUSY
       lea     eax, DWORD PTR [ebp-4]
       push    eax
       push    ABORT                              ;Should be abort | ignore
       push    NULL
       call    VDHPOPUP

       cmp     DWORD PTR [ebp-4], ABORT           ;what response did we get
       je      RequestError
       push    HVDM_CURRENT
       call    VDHKILLVDM
       sub     eax, eax
       push    OFFSET FLAT:MAPSOURCE
       push    OFFSET FLAT:MAPTARGET
       push    VDHMT_PHYSICAL
       call    VDHMAPPAGES

       mov     eax, HVDM_CURRENT
       mov     HVDM_OWNER, eax

       mov     ax, PDB_CURRENT
       mov     PDB_OWNER, ax

       mov     STATUS_BYTE, 0
       mov     WAIT_FOR_STATUS_OUT, FALSE
RequestError:
       mov     WAIT_FOR_EOI, FALSE
       call    ENABLEINTERRUPTS                   ;restore interrupts in the pdd

RequestDirect   ENDP

;********************************************************************
;
; SUBROUTINE NAME:Vdft_Eoi
;
; FUNCTION: This functiion will service the End Of Interrupt isssued by
;           the DOS Isr to the 3270 DFT port.
;           Since the PDD issued the   EOI before notifying the VDD of
;           interrupt,we simply ingnore the EOI and discontinue
;           sending the virtual interrupt.
;
;Method     Routine to service EOI
;           Parameters passed on the stack
;           ebp + 8           pcrf  pointer to the client register frame
;
;
;
;
;
; ENTRY POINT:
; LINKAGE    : CALL NEAR
;              parameters passed on the stack
;              ebp + 8    pcrf    pointer to client register stack frame.
;
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = NONE
;
; EXIT-ERROR:  EAX = NONE
;
;********************************************************************
Vdft_Eoi        PROC NEAR
       push    ebp
       mov     ebp, esp

       push    HVDM_OWNER
       push    HIRQ_DFT
;      call    VDHCLEARVIRR                      ;imported from vpic.lib

       mov     WAIT_FOR_EOI, 0
       cli
       cmp     INTERRUPTSNOTENABLED, 0
       je      VdftEoiError
       mov     eax, WAIT_FOR_EOI
       cmp     WAIT_FOR_STATUS_OUT, eax
       je      VdftEoiError
       call    ENABLEINTERRUPTS                   ;reenable interrupts in the
VdftEoiError:                                     ;pdd
       sti
       leave
       ret     8
Vdft_Eoi        ENDP

;********************************************************************
;
; SUBROUTINE NAME:EnableInterrupts
;
; FUNCTION: This routine will call the physical device driver to
;           enable interrupts, and set the global flag that
;           interrupts have been enabled.
;
; LINKAGE    : CALL NEAR
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = TRUE                    always true.
;
; EXIT-ERROR:  EAX = NONE
;
;********************************************************************
EnableInterrupts        PROC NEAR
        push    ebp
        mov     ebp, esp
        mov     INTERRUPTSNOTENABLED, 0H              ;set up to call the
        push    ENABLE_INTS                           ;pdd and enable ints
        push    0H
        push    0H
        call    PDFTPDDPROC
        mov     eax, TRUE                             ;blindly assume
        leave                                         ;success
        ret
EnableInterrupts        ENDP

;********************************************************************
;
; SUBROUTINE NAME:DisableInterrupts.
;
; FUNCTION: This routine will call the physical device driver to disable
;           interrupts.
;
;
;
;
; LINKAGE    : CALL NEAR  32
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = TRUE
;
; EXIT-ERROR:  EAX = NONE
;
; INTERNAL REFERENCES:  NONE
;
; EXTERNAL REFERENCES:  NONE
;
;********************************************************************
DisableInterrupts       PROC NEAR
        push    ebp
        mov     ebp, esp

        mov     INTERRUPTSNOTENABLED, TRUE              ;set up to
        push    DISABLE_INTS                            ;call the pdd
        push    0H                                      ;and disable interrupts
        push    0H
        call    PDFTPDDPROC
        mov     eax, TRUE                               ;always return successful
        leave
        ret
DisableInterrupts       ENDP

;********************************************************************
;
; SUBROUTINE NAME:VDFTPDDProc
;
; FUNCTION: Routine to service the PDD at interrupt time.
;           This routine will service the interrupt when received from the
;           pdd. It verifies the vdd is the owner. The interrupt will then
;           be passed to the VDM'S context,to be serviced next time the
;           VDM gains context. Vdm task time context.
;
; LINKAGE    : CALL NEAR  32
;
; INPUT:
;              ebp + 20     ulFunc    -request function
;              ebp + 16     f16p1     -parameter 1
;              ebp + 12     f16p2     -parameter 2
;
;
; EXIT-NORMAL: EAX = NONE
;
; EXIT-ERROR:  EAX = NONE
;
;********************************************************************
VdftPddProc     PROC NEAR
        push    ebp
        mov     ebp, esp
        push    ds
        mov     ax, SEG FLAT: DSEG
        mov     ds, ax
        mov     es, ax

        cmp     HVDM_OWNER, 0                     ;make sure vdm has the port
        je      VdftPddDone                       ;as direct access. If not
                                                  ;ignore interrupts

        mov     dx, WORD PTR StatusReg
        in      al,dx
        movzx   eax, al
        mov     STATUS_BYTE, eax

        mov     ax, WORD PTR STATUS_BYTE
        out     dx, al


        mov     INTERRUPTSNOTENABLED, TRUE         ;Send the interrupt to the
        mov     WAIT_FOR_STATUS_OUT, TRUE          ;vdm's context
        mov     WAIT_FOR_EOI, TRUE

        push    HVDM_OWNER
        push    HIRQ_DFT
;       call    VDHSETVIRR                         ;From vpic lib
        sub     eax,eax
        mov     ax, 1

        sub     eax, eax                           ;do a little clean-up
        pop     ecx
        mov     ds, cx
        mov     es, cx

VdftPddDone :
        leave
        retf    12
VdftPddProc     ENDP

;********************************************************************
;
; SUBROUTINE NAME:_VddInit
;
; DESCRIPTIVE NAME:_VddInit
;
; FUNCTION: This is the entry point for the vdd
;           All user hooks are setup in this routine followed by
;           calling the vdhopenpdd service which will return a
;           the entry point in the pdd for the vdd.
;
; ENTRY POINT:
; LINKAGE    : CALL NEAR
;
; INPUT: NONE
;
; EXIT-NORMAL: EAX = NONE
;
; EXIT-ERROR:  EAX = NONE
;
; INTERNAL REFERENCES:  NONE
;
; EXTERNAL REFERENCES:  NONE
;
;********************************************************************
CSEG ENDS
;
;set the init segment as discardable
;
CINIT_TEXT  SEGMENT  DWORD USE32 PUBLIC 'CODE'
_VddInit        PROC NEAR
       push    ebp
       mov     ebp, esp                     ;
                                            ;add in generic routine
                                            ;for command line options
                                            ;set irq,ports

;      int     3                            ;uncomment this for debug

       push    VDM_TERMINATE                ;register the termination
       push    OFFSET FLAT:VDFTTERMINATE    ;routine
       call    VDHINSTALLUSERHOOK
       or      eax, eax
       je      InitFail

       push    VDM_CREATE                   ;register the vdftcreate
       push    OFFSET FLAT:VDFTCREATE
       call    VDHINSTALLUSERHOOK
       or      eax, eax
       je      InitFail

       push    VDM_PDB_CHANGE                     ;register vdftpdbchange
       push    OFFSET FLAT:VDFTPDBCHANGE
       call    VDHINSTALLUSERHOOK
       or      eax, eax
       je      InitFail


       push    VDM_PDB_DESTROY              ;register  vdftpdbdestroy
       push    OFFSET FLAT:VDFTPDBDESTROY
       call    VDHINSTALLUSERHOOK
       or      eax, eax
       je      InitFail


       mov     HIRQ_DFT, eax

       push    OFFSET FLAT: PSZPDDNAME         ;set up to register the vdd with pdd
       push    CS                              ;change this to
                                               ;SEG->our entry point vdftpddproc
                                               ;for selector

       push    OFFSET FLAT:VDFTPDDPROC
       call    VDHOPENPDD
       mov     DWORD PTR PDFTPDDPROC, eax
       mov     WORD PTR PDFTPDDPROC+4, dx
       mov     eax, DWORD PTR PDFTPDDPROC+4
       or      edx, DWORD PTR PDFTPDDPROC      ;did we get a valid pointer
       je      InitFail                        ;to be able to call through
                                               ;see if a selector was
                                               ;returned

InitSucces:
       sub     eax, eax
       mov     eax, TRUE                       ;let the loader know we are
       jmp     InitDone                        ;happy

InitFail :
       sub     eax, eax                        ;zero return to indicate
                                               ;failure

InitDone :
       leave
       ret
_VddInit        ENDP
CINIT_TEXT  ENDS

END     _VddInit                               ;set vddinit as our entry point
