home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / advos2 / ch15 / clock.asm next >
Encoding:
Assembly Source File  |  1988-12-12  |  6.5 KB  |  178 lines

  1.         title   CLOCK - asynchronous periodic timer example
  2.         page    55,132
  3.         .286
  4. ; CLOCK.ASM --- Example of an asynchronous periodic 
  5. ; timer.  Displays the current time at one-second 
  6. ; intervals in the upper-right corner of the screen.
  7. ;
  8. ; Copyright (C) 1987 Ray Duncan 
  9. ;
  10. ; Build:        MASM CLOCK;
  11. ;               LINK CLOCK,,,OS2,CLOCK  
  12. ;
  13. ; Usage:        CLOCK
  14. ;
  15. ; Terminate program with Ctrl-C or Ctrl-Break
  16.  
  17. stdin   equ     0
  18. stdout  equ     1
  19. stderr  equ     2
  20.  
  21. cr      equ     0dh                     ; ASCII carriage return
  22. lf      equ     0ah                     ; ASCII line feed
  23. escape  equ     01bh                    ; ASCII escape code
  24.  
  25.         extrn   DosExit:far
  26.         extrn   DosCreateSem:far
  27.         extrn   DosGetInfoSeg:far
  28.         extrn   DosSemWait:far
  29.         extrn   DosSemSet:far
  30.         extrn   DosTimerStart:far
  31.         extrn   DosWrite:far
  32.  
  33. jerr    macro   target                  ;; Macro to test return code
  34.         local   zero                    ;; in AX and jump if non-zero
  35.         or      ax,ax                   ;; Uses JMP16 to avoid
  36.         jz      zero                    ;; branch out of range errors
  37.         jmp     target
  38. zero:
  39.         endm
  40.  
  41. DGROUP  group   _DATA
  42.  
  43. _DATA   segment word public 'DATA'
  44.  
  45. sname   db      '\SEM\CLOCK.SEM',0      ; name of semaphore
  46. shandle dd      ?                       ; handle of semaphore
  47. semflag dw      0                       ; <>0 if creator of semaphore
  48.  
  49. thandle dw      ?                       ; handle of periodic timer
  50.  
  51. wlen    dw      ?                       ; receives actual length written
  52.  
  53. ten     db      10                      ; used by b2a conversion routine 
  54.  
  55. ginfseg dw      ?                       ; global information segment
  56. linfseg dw      ?                       ; local information segment
  57.  
  58. msg1    db      cr,lf,'Unexpected OS/2 Error',cr,lf
  59. msg1_length equ $-msg1
  60.  
  61. msg2    db      escape,'[s'             ; save cursor position
  62.         db      escape,'[0;70H'         ; move to 0,70
  63. msg2a   db      '00:'                   ; hours
  64. msg2b   db      '00:'                   ; minutes
  65. msg2c   db      '00'                    ; seconds
  66.         db      escape,'[u'             ; restore cursor position
  67. msg2_length equ $-msg2
  68.  
  69. _DATA   ends
  70.  
  71.  
  72. _TEXT   segment word public 'CODE'
  73.  
  74.         assume  cs:_TEXT,ds:DGROUP
  75.  
  76. main    proc    far
  77.  
  78.                                         ; get selectors for info segments
  79.         push    ds                      ; receives global selector
  80.         push    offset DGROUP:ginfseg
  81.         push    ds                      ; receives local selector
  82.         push    offset DGROUP:linfseg
  83.         call    DosGetInfoSeg           ; transfer to OS/2      
  84.         jerr    main2                   ; jump if couldn't get selectors
  85.  
  86.                                         ; create system semaphore...
  87.         push    1                       ; exclusive ownership not needed
  88.         push    ds                      ; variable to receive semaphore handle
  89.         push    offset DGROUP:shandle
  90.         push    ds                      ; address of semaphore name
  91.         push    offset DGROUP:sname
  92.         call    DosCreateSem            ; transfer to OS/2
  93.         jerr    main2                   ; jump if sem already exists
  94.  
  95.         push    0                       ; now create periodic timer...
  96.         push    1000                    ; double word for 1000 msec.
  97.         push    word ptr shandle+2      ; handle of our system semaphore
  98.         push    word ptr shandle
  99.         push    ds                      ; variable to receive timer handle
  100.         push    offset DGROUP:thandle
  101.         call    DosTimerStart           ; transfer to OS/2      
  102.         jerr    main2                   ; jump if timer create failed
  103.  
  104. main1:                                  ; display time at 1-sec intervals
  105.  
  106.                                         ; first set our semaphore...
  107.         push    word ptr shandle+2      ; system semaphore handle
  108.         push    word ptr shandle
  109.         call    DosSemSet               ; transfer to OS/2      
  110.         jerr    main2                   ; terminate if set failed
  111.  
  112.         call    display                 ; display current time
  113.  
  114.         push    word ptr shandle+2      ; wait for 1 second timer
  115.         push    word ptr shandle        ; to be triggered
  116.         push    -1                      ; timeout = -1 = wait indefinitely
  117.         push    -1
  118.         call    DosSemWait              ; transfer to OS/2
  119.         or      ax,ax                   ; did wait fail?
  120.         jz      main1                   ; no, loop to display again
  121.  
  122. main2:                                  ; display error message...
  123.         push    stdout                  ; standard output handle
  124.         push    ds                      ; message address
  125.         push    offset msg1
  126.         push    msg1_length             ; message length
  127.         push    ds                      ; receives actual length written        
  128.         push    offset wlen
  129.         call    DosWrite                ; transfer to OS/2
  130.  
  131.         push    1                       ; terminate all threads
  132.         push    1                       ; return error code
  133.         call    DosExit                 ; final exit to OS/2
  134.  
  135. main    endp
  136.  
  137.  
  138. display proc    near                    ; display current time
  139.  
  140.         mov     es,ginfseg              ; get selector for global
  141.                                         ; read-only information segment 
  142.  
  143.         mov     al,byte ptr es:[8]      ; convert hours to ASCII
  144.         cbw
  145.         div     ten
  146.         add     ax,'00'
  147.         mov     word ptr msg2a,ax
  148.  
  149.         mov     al,byte ptr es:[9]      ; convert minutes to ASCII
  150.         cbw
  151.         div     ten
  152.         add     ax,'00'
  153.         mov     word ptr msg2b,ax
  154.  
  155.         mov     al,byte ptr es:[0ah]    ; convert seconds to ASCII
  156.         cbw
  157.         div     ten
  158.         add     ax,'00'
  159.         mov     word ptr msg2c,ax
  160.  
  161.                                         ; display time...
  162.         push    stdout                  ; standard output handle
  163.         push    ds                      ; address of message
  164.         push    offset msg2
  165.         push    msg2_length             ; length of message
  166.         push    ds                      ; receives bytes written
  167.         push    offset wlen
  168.         call    DosWrite                ; transfer to OS/2
  169.  
  170.         ret                             ; back to caller
  171.  
  172. display endp
  173.  
  174. _TEXT   ends
  175.  
  176.         end     main
  177.