home *** CD-ROM | disk | FTP | other *** search
/ Mega CD-ROM 1 / megacd_rom_1.zip / megacd_rom_1 / DESQVIEW / CMONITOR.ZIP / CMONITOR.ASM < prev    next >
Assembly Source File  |  1988-12-07  |  22KB  |  531 lines

  1.                    TITLE   CMONITOR
  2. PAGE, 132
  3. COMMENT |
  4.  
  5.        Copyright by John Poindexter  Rockville, MD
  6.        Version 1.3  December 7, 1988
  7.  
  8.        xMONITOR Series
  9.  
  10.        This is one of a family of MONITOR programs designed to work with
  11.        applications running in DESQview windows which are not DESQview
  12.        applications, but for which you want to perform some function related
  13.        to their presence in DESQview.
  14.  
  15.        CMONITOR is a DESQview program to be used with DESQview and
  16.        communications programs such as RBBS and COM-AND where you want to
  17.        monitor the presence of a carrier signal in order to re-start the
  18.        program upon a loss of carrier.
  19.  
  20.        xMONITORs use the DESQview API.
  21.  
  22.        Usage:  You must first install the CMONITOR programs in DESQview by
  23.        adding the CM-PIF.DVP file to the DESQview window menu by following
  24.        the standard procedures for adding programs.  Be sure to use CM-PIF.DVP
  25.        since the window must run in background and the window size and memory
  26.        have been reduced to the minimum.  After it is installed you can change
  27.        the command CM for opening the window to whatever you want and you
  28.        will need to change the Parameters line to agree with your location of
  29.        the communications program PIF file, xx-PIF.DVP, and the com port
  30.        to be monitored.
  31.  
  32.        Syntax:   CMONITOR pif_filespec com_port
  33.                                       ^one and only one space
  34.  
  35.        where pif_filespec is the d:\path\xx-PIF.DVP for the main application
  36.        being monitored and com_port is the communications port being used
  37.        by the application (use 1..4 for COM1..COM4).
  38.  
  39.        CMONITOR works in conjuction with CMON.  While in communciations
  40.        program execute CMON d:\path\CM-PIF.DVP from a DOS shell and
  41.        CMONITOR will be loaded and start monitoring the carrier.  When you
  42.        want the monitoring to stop, execute CMON OFF.  CMON will open and
  43.        close the window with CMONITOR.  For the inter-process
  44.        communications that are needed for this to work both the comm PIF
  45.        and CMONITOR PIF must indicate that they share programs.  You
  46.        indicate this by placing an asterisk in the 'Shared Program
  47.        Pathname' field.
  48.  
  49.        CMONITOR checks for the presence of DESQview will not load unless
  50.        it is present.  It is designed to work with DESQview version 2.01.
  51.  
  52.        To terminate CMONITOR just close its window.
  53.  
  54.        Upon restarting, a message with time and date is sent to standard
  55.        output which of course can be redirected to a printer.
  56. |
  57. ;*************************************************************
  58. ;            PROGRAM EQUATES, STRUCTURES AND MACROS
  59. ;*************************************************************
  60.  
  61. include dvapi.inc
  62. cmd_tail           equ     80h
  63. cr                 equ     0dh
  64. lf                 equ     0ah
  65. eol                equ     '$'
  66.  
  67. time_date          struc                           ;for restart message
  68. msg                db      'Restarted at '
  69. hours              db      'hh:'
  70. mins               db      'mm:'
  71. secs               db      'ss '
  72. month              db      'mm/'
  73. day                db      'dd/'
  74. year               db      'yy',cr,lf,eol
  75. time_date          ends
  76.  
  77. ;*************************************************************
  78. ;        CODE SEGMENT BEGINS
  79. ;*************************************************************
  80.  
  81. code_seg           segment
  82.                    assume  cs:code_seg
  83.                    org     100h            ;org = 100h to make this into a
  84.                                            ;".com" file
  85. first:             jmp     load_monitor
  86.  
  87. ;*************************************************************
  88. ;        PROGRAM DATA
  89. ;*************************************************************
  90.  
  91. version            equ     'Version 1.3'
  92.                    db      'CMONITOR.COM'
  93.                    db      'Copyright by John Poindexter'
  94.                    db      version
  95.                    db      '7DEC88'
  96.  
  97.                    align   2
  98. PSP_seg            dw      ?
  99. com_port_msr       label   word     ;table of addresses of modem status registers
  100. com1               dw      03feh
  101. com2               dw      02feh
  102. com3               dw      03eeh
  103. com4               dw      02eeh
  104. com_msr            dw      0
  105.  
  106. ;DESQview data
  107. main               label   dword
  108. main_win           dw      2 dup (0)
  109.  
  110. top                label   dword
  111. top_window         dw      2 dup (0)
  112.  
  113. mon_mailbox        db      'CMONITOR'
  114. lmon_mailbox       equ     $-mon_mailbox
  115.  
  116. mail_waiting       dd      0
  117.  
  118. move_fore_msg      db      1bh,10h          ;window manager stream id
  119.                    dw      lmove_fore_msg-4
  120.                    db      0c1h             ;make foreground
  121. lmove_fore_msg     equ     $-move_fore_msg  ;length of msg
  122.  
  123. pif_buffer         db      416 dup (?)
  124.  
  125. install_message db      cr,lf
  126.                 db      'CMONITOR ',version,' installed.'
  127.                 db      cr,lf,eol
  128. fail_message1   db      cr,lf
  129.                 db      'ERROR - No carrier detected on port specified.'
  130.                 db      cr,lf,eol
  131. fail_message3   db      cr,lf
  132.                 db      'ERROR - DESQview is not present.'
  133.                 db      cr,lf,eol
  134. file_error_msg  db      cr,lf
  135.                 db      'ERROR - Unable to open PIF file for Communications '
  136.                 db      'program.'
  137.                 db      cr,lf,eol
  138. bad_handle_msg  db      cr,lf
  139.                 db      'ERROR - Got a bad handle from main program.'
  140.                 db      cr,lf,eol
  141. clock_msg       time_date   <>
  142.  
  143. ;*************************************************************
  144. ;                    MONITOR PROCEDURE
  145. ; This keeps track of whether there is a carrier detected on
  146. ; the COM port being monitored.
  147. ;*************************************************************
  148.  
  149. monitor            proc    near
  150.  
  151. begin_monitor:
  152.                    @send   sizeof,mailme   ;check for mail waiting
  153.                    @pop    mail_waiting
  154.                    xor     ax,ax
  155.                    xor     bx,bx
  156.                    @cmp    mail_waiting    ;was there any
  157.                    je      check_carrier   ;no, so continue checking
  158.                    jmp     finished        ;yes, must be CLOSE msg
  159.  
  160. check_carrier:     mov     dx,com_msr      ;check for carrier
  161.                    in      ax,dx
  162.                    test    ax,10000000b    ;carrier detect is bit 7
  163.                    jz      lost_carrier
  164.                    jmp     recycle
  165.  
  166. lost_carrier:      @call   pause           ;add some delay
  167.                    @send   free,main       ;close the main window
  168.  
  169. ;get window handle for window at 0,0 so can return
  170.  
  171.                    xor     ax,ax              ;start search from top of list
  172.                    mov     es,ax
  173.                    xor     bx,bx              ;look at position 0,0
  174.                    @call   locate
  175.                    mov     ax,es
  176.                    test    ax,ax              ;was a window found
  177.                    jz      re_load            ;no, go ahead and reload
  178.                    mov     top_window[2],ax   ;save handle of window found
  179.                    mov     top_window, 0      ;make sure low word is zero
  180.  
  181. ;open new process for main application
  182. re_load:           push    ds              ;point to PIF buffer
  183.                    pop     es
  184.                    lea     di,pif_buffer
  185.                    mov     bx,416
  186.                    @call   newproc         ;open main application in DV
  187.                    mov     main_win[2],bx  ;get handle - high order word
  188.                    mov     main_win,0      ;make sure low order is zero
  189.  
  190.                    call    clock           ;send out restart message
  191.                    lea     dx,clock_msg
  192.                    call    prints
  193.  
  194. ;return to what you were doing, by switching back to original top window
  195.                    lea     si,move_fore_msg   ;setup to send message
  196.                    xor     dx,dx
  197.                    mov     cx,lmove_fore_msg
  198.                    @push   dssi
  199.                    @push   dxcx
  200.                    @send   write,top          ;msg to move to foreground
  201.  
  202.                    jmp     finished
  203.  
  204. recycle:           @call   pause           ;give up rest of time slice
  205.                    jmp     begin_monitor   ;go back for another check
  206.  
  207. finished:          ret
  208.  
  209. monitor            endp
  210.  
  211. ;*************************************************************
  212. ;       CNVRT1 PROCEDURE CONVERTS  16 BIT INTEGERS TO ASCII
  213. ;*************************************************************
  214. ;                  Call with:     AX = integer
  215. ;                  Returns with:  AX = ASCII
  216. ;                  Preserves all other registers
  217.  
  218. cnvrt1             proc    near
  219.                    aam                     ;make al into bcd
  220.                    or      ax,'00'         ; and to ascii
  221.                    xchg    al,ah
  222.                    ret
  223. cnvrt1             endp
  224.  
  225. ;*************************************************************
  226. ;       CLOCK PROCEDURE GETS TIME OF DAY AND DATE
  227. ;*************************************************************
  228. ;                  Call with:     a variable of time_date structure
  229. ;                  time_date          struc
  230. ;                  hours              db      'hh:'
  231. ;                  mins               db      'mm '
  232. ;                  month              db      'mm/'
  233. ;                  day                db      'dd/'
  234. ;                  year               db      'yy',cr,lf,eol
  235. ;                  time_date          ends
  236.  
  237. clock              proc    near
  238.                    push    ax
  239.                    push    bx
  240.                    push    cx
  241.                    push    dx
  242.  
  243.                    mov     ah,2ah          ;get date
  244.                    int     21h
  245.                    sub     cx,1900         ; last two digits
  246.                    mov     ax,cx           ;make readable
  247.                    call    cnvrt1          ;convert to ascii
  248.                    mov     word ptr clock_msg.year,ax
  249.                    xchg    al,dh           ;get month
  250.                    call    cnvrt1          ;convert to ascii
  251.                    mov     word ptr clock_msg.month,ax
  252.                    xchg    al,dl           ;get day
  253.                    call    cnvrt1          ;convert to ascii
  254.                    mov     word ptr clock_msg.day,ax
  255.  
  256.                    mov     ah,2ch          ;get time
  257.                    int     21h
  258.                    xchg    al,ch           ;get hours
  259.                    call    cnvrt1          ;convert to ascii
  260.                    mov     word ptr clock_msg.hours,ax
  261.                    xchg    al,cl           ;get minutes
  262.                    call    cnvrt1          ;convert to ascii
  263.                    mov     word ptr clock_msg.mins,ax
  264.                    xchg    al,dh           ;get seconds
  265.                    call    cnvrt1          ;convert to ascii
  266.                    mov     word ptr clock_msg.secs,ax
  267.  
  268.                    pop     dx
  269.                    pop     cx
  270.                    pop     bx
  271.                    pop     ax
  272.                    ret
  273. clock              endp
  274.  
  275. ;*************************************************************
  276. ;  PRINTS PROCEDURE LIKE INT21H FUNCTION 9 BUT REDIRECTABLE
  277. ;*************************************************************
  278. ;     Call with:     DX = offset to string ending with $
  279. ;     Preserves all other resgisters
  280.  
  281. prints             proc    near
  282.                    push    si
  283.                    push    bx
  284.                    push    cx
  285.                    mov     si,dx           ; ptr to string text
  286.                    sub     cx,cx           ; overall text length
  287. ps1:               lodsb
  288.                    cmp     al,eol          ; ending $ ?
  289.                    je      ps9
  290.                    inc     cx
  291.                    jmp     short ps1
  292.  
  293. ps9:
  294.                    mov     bx,1            ; standard output device
  295.                    mov     ah,40h          ;  to write to
  296.                    int     21h
  297.  
  298.                    pop     cx              ; recover registers
  299.                    pop     bx
  300.                    pop     si
  301.                    ret
  302. prints             endp
  303.  
  304. ;********************************************************************
  305. ;             ARGV PROCEDURE to get command line arguments
  306. ;********************************************************************
  307. ;                  Call with:  ES:BX = command line address
  308. ;                              (implicit: ES=PSP segment)
  309. ;                              AX    = argument number (0 based)
  310. ;
  311. ;                  Returns:    ES:BX = argument address
  312. ;                              AX    = argument length
  313. ;                              (0=argument not found)
  314. ;                  Other registers preserved.
  315. ;
  316. ; If called with AX=0 (argv[0]) and running under
  317. ; MS-DOS version 3.0 or later, returns ES:BX pointing
  318. ; to program name in environment block and AX=length,
  319. ; otherwise returns ES:BX unchanged and AX=0.
  320. ;
  321.  
  322. cr      equ     0dh             ; ASCII carriage return
  323. lf      equ     0ah             ; ASCII line feed
  324. tab     equ     09h             ; ASCII tab
  325. blank   equ     20h             ; ASCII space character
  326. eqsign  equ     3dh             ; ASCII equal sign
  327.  
  328. argv    proc    near
  329.         or      ax,ax           ; is it argument 0?
  330.         jz      argv8           ; yes, jump to get program name
  331.  
  332.         xor     ah,ah           ; initialize argument counter
  333.  
  334. argv1:  mov     cx,-1           ; set flag = outside argument
  335.  
  336. argv2:  inc     bx              ; point to next character
  337.         cmp     byte ptr es:[bx],cr
  338.         je      argv7           ; exit if carriage return
  339.         cmp     byte ptr es:[bx],blank
  340.         je      argv1           ; outside argument if ASCII blank
  341.         cmp     byte ptr es:[bx],tab
  342.         je      argv1           ; outside argument if ASCII tab
  343.         cmp     byte ptr es:[bx],eqsign
  344.         je      argv1           ; outside argument if ASCII equal sign
  345.  
  346.                                 ; if not blank, tab or equal sign...
  347.         jcxz    argv2           ; jump if already inside argument
  348.  
  349.         inc     ah              ; else count arguments found
  350.         cmp     ah,al           ; is this the one we're looking for?
  351.         je      argv4           ; yes, go find its length
  352.         not     cx              ; no, set flag = inside argument
  353.         jmp     argv2           ; and look at next character
  354.  
  355. argv4:                          ; found desired argument, now
  356.                                 ; determine its length...
  357.         mov     ax,bx           ; save param. starting address
  358.  
  359. argv5:  inc     bx              ; point to next character
  360.         cmp     byte ptr es:[bx],cr
  361.         je      argv6           ; found end if carriage return
  362.         cmp     byte ptr es:[bx],blank
  363.         je      argv6           ; found end if ASCII blank
  364.         cmp     byte ptr es:[bx],tab
  365.         je      argv6           ; found end if ASCII tab
  366.         cmp     byte ptr es:[bx],eqsign
  367.         jne     argv5           ; found end if ASCII equal sign
  368.  
  369. argv6:  xchg    bx,ax           ; set ES:BX = argument address
  370.         sub     ax,bx           ; and AX = argument length
  371.         jmp     argvx           ; return to caller
  372.  
  373. argv7:  xor     ax,ax           ; set AX = 0, argument not found
  374.         jmp     argvx           ; return to caller
  375.  
  376. argv8:                          ; special handling for argv=0
  377.         mov     ax,3000h        ; check if DOS 3.0 or later
  378.         int     21h             ; (force AL=0 in case DOS 1)
  379.         cmp     al,3
  380.         jb      argv7           ; DOS 1 or 2, return null param.
  381.         mov     es,es:[2ch]     ; get environment segment from PSP
  382.         xor     di,di           ; find the program name by
  383.         xor     al,al           ; first skipping over all the
  384.         mov     cx,-1           ; environment variables...
  385.         cld
  386. argv9:  repne scasb             ; scan for double null (can't use
  387.         scasb                   ; (SCASW since might be odd addr.)
  388.         jne     argv9           ; loop if it was a single null
  389.         add     di,2            ; skip count word in environment
  390.         mov     bx,di           ; save program name address
  391.         mov     cx,-1           ; now find its length...
  392.         repne scasb             ; scan for another null byte
  393.         not     cx              ; convert CX to length
  394.         dec     cx
  395.         mov     ax,cx           ; return length in AX
  396.  
  397. argvx:                          ; common exit point
  398.         ret                     ; return to caller
  399.  
  400. argv    endp
  401.  
  402. ;****************************************************************************
  403. ;                       INITIALIZATION PROCEDURE
  404. ;****************************************************************************
  405.  
  406. load_monitor       proc    near
  407.  
  408.                    assume  cs:code_seg, ds:code_seg, es:nothing
  409.  
  410.                    mov     PSP_seg,es      ;save PSP
  411.  
  412. ;make sure this is a DESQview environment
  413.  
  414. chk_dv:            @call   dvpresent
  415.                    test    ax,ax
  416.                    jnz     chk_level
  417.                    lea     dx,fail_message3
  418.                    jmp     test_failed
  419. chk_level:         mov     bx,200h
  420.                    @call   apilevel        ;requires version 2.00+
  421.  
  422. ;DESQview actions
  423. ;setup to open main application if carrier is lost
  424.  
  425. install:           mov     bx,cmd_tail     ;setup to get command line arg
  426.                    mov     es,PSP_seg
  427.                    mov     ax,1            ;get first argument
  428.                    call    argv
  429.                    mov     di,ax
  430.                    mov     byte ptr es:[di+bx],0 ;make filespec ASCIIZ
  431.  
  432.                    mov     al,byte ptr es:[di+bx+1] ;get the second argument
  433.                    sub     al,31h          ;convert to binary and adjust
  434.                    push    bx              ;save it
  435.                    mov     bl,al
  436.                    shl     bl,1            ;double it for table lookup
  437.                    xor     bh,bh
  438.                    mov     ax,com_port_msr[bx]
  439.                    mov     com_msr,ax      ;save address of com port msr
  440.                    pop     bx
  441.  
  442.                    push    ds              ;save DS
  443.                    mov     ax,es           ;point to ASCIIZ filespec
  444.                    mov     ds,ax
  445.                    mov     dx,bx
  446.                    mov     ax,3d00h        ;open file for reading
  447.                    int     21h
  448.                    pop     ds
  449.                    jnc     read_file
  450.                    lea     dx,file_error_msg
  451.                    jmp     test_failed
  452.  
  453. read_file:         mov     bx,ax           ;get file handle
  454.                    lea     dx,pif_buffer
  455.                    mov     cx,416          ;DV 2.00 PIFs are 416 bytes
  456.                    mov     ah,3fh          ;read file
  457.                    int     21h
  458.                    mov     ah,3eh          ;close file
  459.                    int     21h
  460.  
  461. ;make sure starting off with carrier on com port specified
  462.  
  463.                    mov     dx,com_msr
  464.                    in      ax,dx
  465.                    test    ax,10000000b
  466.                    jnz     success
  467.                    lea     dx,fail_message1
  468.                    jmp     test_failed
  469.  
  470. success:           lea     dx,install_message
  471.                    mov     ah,9
  472.                    int     21h             ;report installed
  473.  
  474. ;get handle of main application
  475.  
  476. get_main:          @call   pause           ;let CMON finish
  477.                    @send   read,mailme     ;get message from main with handle
  478.                    @pop    dxcx            ;clear out stack
  479.                    @pop    essi            ;clear out stack
  480.                    @send   addr,mailme     ;get address of main
  481.                    @pop    main
  482.                    @mov    esdi,main       ;make sure we got a good handle
  483.                    @call   isobj
  484.                    test    bx,bx
  485.                    jnz     good_handle
  486.                    lea     dx,bad_handle_msg
  487.                    jmp     test_failed
  488.  
  489. ;name this mailbox so CMON can find it
  490.  
  491. good_handle:       lea     si,mon_mailbox
  492.                    xor     dx,dx
  493.                    mov     cx,lmon_mailbox
  494.                    @push   dssi
  495.                    @push   dxcx
  496.                    @send   setname,mailme
  497.  
  498. ;get window handle for window at 0,0 and make it foreground
  499.  
  500.                    xor     ax,ax              ;start search from top of list
  501.                    mov     es,ax
  502.                    xor     bx,bx              ;look at position 0,0
  503.                    @call   locate
  504.                    mov     ax,es
  505.                    test    ax,ax              ;was a window found
  506.                    jz      start_monitor      ;no, go ahead and monitor
  507.                    mov     top_window[2],ax   ;save handle of window found
  508.                    lea     si,move_fore_msg   ;setup to send message
  509.                    xor     dx,dx
  510.                    mov     cx,lmove_fore_msg
  511.                    @push   dssi
  512.                    @push   dxcx
  513.                    @send   write,top          ;msg to move to foreground
  514.  
  515. start_monitor:     call    monitor         ;go wait for carrier loss
  516.  
  517.                    mov     ax,4c00h        ;normal exit
  518.                    int     21h             ;
  519.  
  520. test_failed:       @call   pause           ;let CMON finish up
  521.                    mov     ah,9            ;if not get back to DOS after
  522.                    int     21h             ;printing error message
  523.                    mov     ax,4c01h        ;and returning errorlevel
  524.                    int     21h             ;
  525.  
  526. load_monitor       endp
  527.  
  528. code_seg           ends
  529.  
  530.                    end     first           ;begin at first
  531.