Metropoli BBS
VIEWER: checkdv.asm MODE: TEXT (ASCII)
comment ~
/*@H************************ < Mylibrary       > ****************************
*                                                                           *
*   CHECKDV  : checkdv.asm API routines to check for Desqview               *
*                                                                           *
*   Author   : Donald J. Gloistein                                          *
*                                                                           *
*   Program, Source, Documentation (c) 1987, all rights reserved.           *
*                                                                           *
*   Compiled code may be used in your library, and linked to your programs  *
*   BUT, the source code nor a library based on the compiled modules may be *
*   commercially distributed.                                               *
*   This is not shareware, no donation is expected. But I do retain rights  *
*   to the source.                                                          *
*                                                                           *
*   See manual for license and information to general public.               *
*   Any code derived from other sources will be noted in comments.          *
*                                                                           *
*                                                                           *
*---------------------------  Module Description  --------------------------*
*  This code was based closely on the samples provided by Quarterdeck for   *
*  their version 2 Desqview (tm).  Modifications made to use C calling      *
*  conventions and initialize global variables for the program to use.      *
*                                                                           *
*                                                                           *
*                                                                           *
*   Function names:                                                         *
*     int dv_get_dv_version(void)                                           *
*     unsigned int dv_get_video_buffer(unsigned int)                        *
*     void dv_pause(void)                                                   *
*     void dv_begin_critical(void)                                          *
*     void dv_end_critical(void)                                            *
*   Globals that can be used:                                               *
*     int in_dv               True if dv present                            *
*     unsigned dv_vid_seg     segment address of buffer                     *
*     unsigned dv_vid_off     offset of buffer (usually 0)                  *
*     int dv_maj_version      major version number if in_dv                 *
*     int dv_min_version      minor version number if in_dv                 *
*                                                                           *
*                                                                           *
*--------------------------- Implementation Notes --------------------------*
*                                                                           *
*   compiled with :                                                         *
*   compiled by   : MASM v.5.0                                              *
*                                                                           *
*   linked with   : MYLIB.LIB                                               *
*   linked by     : MICROSOFT LINK                                          *
*                                                                           *
*   As written, this module is set for the C calling conventions of         *
*   Microsoft C version 5.0, it takes advantage of none of the upgraded     *
*   options of Masm 5.0, especially the memory model feature. This may not  *
*   be true in the future.                                                  *
*   It is designed to be called with model defined or small memory is       *
*   assumed.  This is done on the command line as follows:                  *
*         masm /MX /Dsmall filename ;      gives small model                *
*         mams /MX /Dmedium filename ;     gives medium model               *
*   While it is not necessary to define small, it is included to help in    *
*   batch files.                                                            *
*                                                                           *
*   The dv_get_video_buffer() makes a call to dv_get_version(), so only one *
*   need be used. After the call, your program can use the in_dv variable   *
*   to test if Desqview is present.  If your program does direct screen     *
*   writes, use the get buffer function.  Then the shadow area DV uses will *
*   be in the variables dv_vid_seg and dv_vid_off.  These can be used with  *
*   straight copying functions.  No timing loops are needed, as DV takes    *
*   care of that. If your program uses only BIOS, DOS or the shadow buffer  *
*   then it will run in a small window in Desqview.  I have modified Windows*
*   BOSS for Desqview, and my BATMEN program now runs in DV with no bleeding*
*                                                                           *
*   The other functions are fairly self explanatory. I use the dv_pause()   *
*   when I am in an inkey loop polling for a key stroke.  This speeds up    *
*   the other programs somewhat. The critical functions would be well used  *
*   when setting things like interupts and signals. Anytime that you do not *
*   want to loose program control.                                          *
*                                                                           *
*   problems: none <grin>, I assume people will tell me. Works for me.      *
*   Desqview version 2.0 has a bug and returns the version in reverse order *
*    this version allows for it.                                            *
*                                                                           *
*   I have only tested this under desqview version 2                        *
*                                                                           *
*---------------------------      Author(s)        -------------------------*
*     Initials ---- Name ---------------------------------                  *
*      DjG          Donald J. Gloistein                                     *
*                                                                           *
*************************************************************************@H*/

/*@R************************< Revision History >*****************************
*                                                                           *
*   version -- date -- init ---Notes----------------------                  *
*    1.00    12-14-87  DjG  Modified code from DV v2.00 manual              *
*    1.01    01-16-88  DjG  Fixed bug in interface. My fault.               *
*    1.02    01-20-88  DjG  Adjusted for DV 2.0                             *
*                                                                           *
*************************************************************************@R*/
~ end_of_comments

TRUE    EQU     1
FALSE   EQU     0

if1
ifdef SMALL
LDATA   EQU     FALSE
LCODE   EQU     FALSE
%out    Small model defined
endif
ifdef MEDIUM
LDATA   EQU     FALSE
LCODE   EQU     TRUE
%out Medium model defined
endif
ifdef LARGE
LDATA   EQU     TRUE
LCODE   EQU     TRUE
%out Large model defined
endif
ifdef COMPACT
LDATA   EQU     TRUE
LCODE   EQU     FALSE
%out Compact model defined
endif

ifndef LDATA
LDATA   EQU     FALSE
LCODE   EQU     FALSE
%out  code not defined assuming small model
endif
if  LDATA
%out    LARGE DATA
else
%out    SMALL DATA
endif
if  LCODE
%out    LARGE CODE
else
%out    SMALL CODE
endif
endif

if LCODE
CHECKDV_TEXT   SEGMENT  WORD PUBLIC 'CODE'
CHECKDV_TEXT   ENDS
else
_TEXT   SEGMENT  WORD PUBLIC 'CODE'
_TEXT   ENDS
endif

CONST   SEGMENT  WORD PUBLIC 'CONST'
CONST   ENDS
_BSS    SEGMENT  WORD PUBLIC 'BSS'
_BSS    ENDS
_DATA   SEGMENT  WORD PUBLIC 'DATA'
_DATA   ENDS

if LCODE
DGROUP  GROUP   CONST,  _BSS,   _DATA
        ASSUME  CS: CHECKDV_TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
else
DGROUP  GROUP   CONST,  _BSS,   _DATA
        ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
endif

if LCODE
extrn  __chkstk:far
else
extrn  __chkstk:near
endif

_DATA   segment
        public _dv_vid_seg
        public _dv_vid_off
        public _in_dv
        public _dv_maj_version
        public _dv_min_version

_dv_vid_seg dw 0
_dv_vid_off dw 0
_in_dv      dw 0
_dv_maj_version dw  0
_dv_min_version dw  0
_DATA   ends

if      LCODE
@AB     EQU     6
else
@AB     EQU     4
endif

ARG1    EQU     @AB
ARG2    EQU     @AB+2
ARG3    EQU     @AB+4
ARG4    EQU     @AB+6
ARG5    EQU     @AB+8
ARG6    EQU     @AB+10

if LCODE
CHECKDV_TEXT   segment
else
_TEXT segment
endif

    public  _dv_get_version
    public  _dv_get_video_buffer
    public  _dv_pause
    public  _dv_begin_critical
    public  _dv_end_critical

comment ~
/*@F*************************< dv_get_version>*******************************
*                                                                           *
*                      checks for Desqview and version                      *
*                      ---------------------------------                    *
*                                                                           *
*   Checks for presence of desqview. Sets the major and minor version       *
*   global variables. Sets in_dv variable to true if present                *
*                                                                           *
*   Parameters:                                                             *
*       no parameters                                                       *
*       ...             ...                                                 *
*                                                                           *
*   Returns:                                                                *
*       major version number is returned in AX                              *
*       False (0) is returned if not desqview                               *
*************************************************************************@F*/
~ end_of_comments


if      LCODE
_dv_get_version    proc    far
else
_dv_get_version    proc    near
endif
        push    bp
        mov     bp,sp
        push    bx
        push    cx
        push    dx
        mov     cx,'DE'      ;set cx and dx to invalid date
        mov     dx,'SQ'
        mov     ax,2b01h     ;dos set date function
        int     21h
        cmp     al,0ffh      ; did dos set date as invalid?
        je      no_desqview   ; if so, desqview isn't there
        mov     ax,bx        ; AH=major version AL = minor version
        mov     _in_dv,1     ;
        cmp     ax,0002h     ; corrects for bug, version 2.0 reverses the
        jne     not_20       ; documented version order.  Comment out
        xchg    al,ah        ; these three lines if it doesnt matter to you.
not_20:
        mov     byte ptr _dv_maj_version,ah  ; not needed, but I want it
        mov     byte ptr _dv_min_version,al
        xchg    al,ah        ; get major version in al
        cbw                  ; set up for return
        jmp     short dvgv_x
no_desqview:
        xor     ax,ax        ;return false (no desqview)
dvgv_x: pop     dx
        pop     cx
        pop     bx
        pop     bp
        ret
_dv_get_version  endp

comment ~
/*@F*************************< dv_get_video_buffer >*************************
*                                                                           *
*                      finds the video buffer DV is using                   *
*                      ---------------------------------                    *
*                                                                           *
*   Finds the buffer for direct video screen writing                        *
*                                                                           *
*   unsigned int dv_get_video_buffer(segment)                               *
*   Parameters:                                                             *
*       segment         unsigned int                                        *
*                                                                           *
*   Returns:                                                                *
*       the passed segment if no desqview, new segment if DV is there       *
*       returned value is an unsigned integer.                              *
*       sets up the dv_vid_seg and dv_vid_off to new segments               *
*       otherwise sets them to the current segment with 0 offset            *
*                                                                           *
*************************************************************************@F*/
~ end_of_comments


if      LCODE
_dv_get_video_buffer   proc    far
else
_dv_get_video_buffer   proc    near
endif
        push    bp
        mov     bp,sp
        push    di
        push    si         ; lets make sure
        push    es
        mov     es,[bp][ARG1]
        call    _dv_get_version
        test    ax,ax      ; in DV?
        jz      dvgvb_x
        ;since DV is running, get the alternate buffer
        mov     ah,0feh     ; DV's get buffer function
        int     10h         ; returns es:di as alternate buffer
        mov     _dv_vid_off,di
dvgvb_x:
        mov     ax,es       ;return the video segment
        mov     _dv_vid_seg,ax  ; set up the global
        pop     es
        pop     si
        pop     di
        mov     sp,bp
        pop     bp
        ret
_dv_get_video_buffer  endp


comment ~
/*@F*************************< api_call      >*******************************
*                                                                           *
*                      invokes a desqview interface func                    *
*                      ---------------------------------                    *
*                                                                           *
*   local procedure to invoke desqview API after switching to a stack that  *
*   Desqview provides for the programmer                                    *
*                                                                           *
*   Parameters:                                                             *
*       local procedure, does not follow C calling convention.              *
*       AX contains the function to be invoked                              *
*                                                                           *
*   Returns:                                                                *
*       none                                                                *
*                                                                           *
*************************************************************************@F*/
~ end_of_comments


api_call      proc    near
        mov     ax,101ah      ; the func to switch to DV's stack
        int     15H           ; DV's software interupt
        mov     ax,bx         ; move the desired fuction to ax
        int     15H
        mov     ax,1025h      ; the func to swith off of DV's stack
        int     15H
        ret
api_call  endp

comment ~
/*@F*************************< dv_pause      >*******************************
*                                                                           *
*                      gives up programs time slice                         *
*                      ---------------------------------                    *
*                                                                           *
*   When the calling program is just polling the key board waiting for      *
*   something to happen, it can use up a lot of time. This releases the     *
*   rest of the time, like if you are using an inkey type loop              *
*                                                                           *
*     void dv_pause(void);                                                  *
*                                                                           *
*   Parameters:  none                                                       *
*                                                                           *
*   Returns:     nothing                                                    *
*                                                                           *
*************************************************************************@F*/
~ end_of_comments


if      LCODE
_dv_pause      proc    far
else
_dv_pause      proc    near
endif
        cmp     byte ptr _in_dv,1      ; are we in desqview ?
        jne     dvp_x
        mov     bx,1000h              ; put function code in ax
        call    api_call
dvp_x:  ret
_dv_pause  endp


comment ~
/*@F*************************< dv_begin_critical >***************************
*                                                                           *
*                      keeps time slice in desqview                         *
*                      ---------------------------------                    *
*                                                                           *
*   This function tells Desqview not to give up your time slice.            *
*   This is used for parts of your program that are critical and you do not *
*   want interupted.                                                        *
*                                                                           *
*      void dv_begin_critical(void)                                         *
*   Parameters:     none                                                    *
*                                                                           *
*   Returns:        nothing                                                 *
*                                                                           *
*************************************************************************@F*/
~ end_of_comments


if      LCODE
_dv_begin_critical    proc    far
else
_dv_begin_critical   proc    near
endif
        cmp     byte ptr _in_dv,1
        jne     dvbc_x
        mov     bx,101bH     ; make the begin critical call
        call    api_call
dvbc_x: ret
_dv_begin_critical  endp


comment ~
/*@F*************************< dv_end_critical >*****************************
*                                                                           *
*                      ends the critical time slice                         *
*                      ---------------------------------                    *
*                                                                           *
*   This function tells Desqview to end the critical time slice.            *
*                                                                           *
*      void dv_end_critical(void)                                           *
*   Parameters:     none                                                    *
*                                                                           *
*   Returns:        nothing                                                 *
*                                                                           *
*************************************************************************@F*/
~ end_of_comments


if      LCODE
_dv_end_critical    proc    far
else
_dv_end_critical   proc    near
endif
        cmp     byte ptr _in_dv,1
        jne     dvec_x
        mov     bx,101cH     ; make the begin critical call
        call    api_call
dvec_x: ret
_dv_end_critical  endp

if LCODE
CHECKDV_TEXT   ends
else
_TEXT   ends
endif
   end
[ RETURN TO DIRECTORY ]