home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: InfoMgt / InfoMgt.zip / WAKEUP.ZIP / WAKEUP.ASM next >
Assembly Source File  |  1988-04-26  |  9KB  |  306 lines

  1. ;-------------------------------------------------------
  2. ; WAKEUP.ASM -- OS/2 Detachable Alarm Program
  3. ; Copyright (c) 1988, Ziff Communications Co.
  4. ; PC Magazine * Charles Petzold
  5. ;-------------------------------------------------------
  6.  
  7.         .286C
  8.         DOSSEG
  9.         .MODEL    SMALL
  10.         .STACK    0200h
  11.  
  12.     ; ---------------------------------------------
  13.     ;  OS/2 External Functions and Data Structures
  14.     ; ---------------------------------------------
  15.  
  16.         EXTRN    DosBeep:FAR, DosExit:FAR, DosGetDateTime:FAR        EXTRN    DosSleep:FAR, DosWrite:FAR, KbdCharIn:FAR
  17.         EXTRN    KbdFlushBuffer:FAR, VioEndPopUp:FAR, VioPopUp:FAR
  18.         EXTRN    VioSetCurPos:FAR, VioWrtNAttr:FAR, VioWrtTTY:FAR, 
  19.  
  20. DateTimeStruc    STRUC
  21.             hour        db    ?
  22.             minutes        db    ?
  23.             seconds        db    ?
  24.             hundreths    db    ?
  25.             day        db    ?
  26.             month        db    ?
  27.             year        dw    ?
  28.             timezone    dw    ?
  29.             day_of_week    db    ?
  30. DateTimeStruc    ENDS
  31.  
  32. KeyDataStruc    STRUC
  33.             char_code    db    ?
  34.             scan_code    db    ?
  35.             status        db    ?
  36.             nls_shift    db    ?
  37.             shift_state    dw    ?
  38.             time        dd    ?
  39. KeyDataStruc    ENDS
  40.                     ; --------------------------
  41.         .DATA            ;  Initialized Data Segment
  42.                     ; --------------------------
  43.  
  44. SyntaxMsg    db    13, 10,     "Syntax: DETACH WAKEUP hour:minute"
  45.         db    13, 10, 10, 9,      "Use 24-hour time format."
  46.         db    13, 10, 10, "(c) 1988, Ziff Communications Co."
  47.         db      13, 10,     "PC Magazine ",254, "Charles Petzold"
  48.         db    13, 10
  49. SyntaxMsgLen    equ    $ - SyntaxMsg
  50.         db    10,         "Press any key to return to OS/2..."
  51. SyntaxMsgLen2    equ    $ - SyntaxMsg
  52.  
  53. WakeupMsg    db    "WAKE UP!  WAKE UP!  WAKE UP!"
  54. WakeupMsgLen    equ    $ - WakeupMsg
  55.  
  56. Delimiters    db    9, " ,;="
  57. PopupFlag    dw    1
  58. Attribute    db    4Fh, 74h
  59.                     ; ----------------------------
  60.         .DATA?            ;  Uninitialized Data Segment
  61.                     ; ----------------------------
  62. BytesWritten    dw    ?
  63. DateTime    DateTimeStruc <>
  64. KeyData        KeyDataStruc <>
  65.                     ; --------------
  66.         .CODE            ;  Code Segment
  67.                     ; --------------
  68.         ASSUME    ES:DGROUP
  69.  
  70. ; ---------------------------------------------
  71. ;  Parse command line to find the wake-up time
  72. ; ---------------------------------------------
  73.  
  74. Entry:        Push    DS            ; Data segment selector
  75.         Pop    ES            ; Transfer it to ES
  76.         Mov    DS, AX            ; DS = Environment selector
  77.         Mov    SI, BX            ; SI = Start of command line
  78.         Sub    AH, AH            ; A little preparation 
  79.  
  80.                         ; Skip name and delimiters
  81.                         ; ------------------------
  82.  
  83. SkipProgName:    Lodsb                ; Pull a command line byte
  84.         Or    AL, AL            ; Check if it's zero
  85.         Jnz    SkipProgName        ; If not, continue
  86.  
  87. SkipDelims:    Lodsb                ; Get another byte
  88.         Or    AL, AL            ; See if it's zero
  89.         Jz    ParamError        ; If so, that's no good
  90.  
  91.         Mov    DI, Offset Delimiters    ; All possible delimiters
  92.         Mov    CX, 5            ; Five of them
  93.         Repnz    Scasb            ; Scan for a match
  94.         Jz    SkipDelims        ; If match, try another byte
  95.  
  96.                         ; Calculate Hour
  97.                         ; --------------
  98.  
  99.         Call    NumberTrans        ; Translate ASCII byte
  100.  
  101.         Mov    DX, AX            ; Save first 'hour' byte in DL
  102.  
  103.         Lodsb                ; Get second 'hour' byte
  104.         Cmp    AL, ':'            ; See if it'a a colon
  105.         Jz    GotHour            ; If so, hour is finished
  106.  
  107.         Call    NumberTrans        ; If not, translate it
  108.  
  109.         IMul    DX, 10            ; Multiply first byte by 10
  110.         Add    DL, AL            ; Add the second byte
  111.         Cmp    DL, 24            ; Check if hour is 24 or above
  112.         Jae    ParamError        ; What clock do you use? 
  113.  
  114.         Lodsb                ; Get next byte
  115.         Cmp    AL, ':'            ; Should be colon
  116.         Jnz    ParamError        ; If not, it's an error
  117.  
  118. GotHour:    IMul    DX, 60            ; DX has minutes since midnight
  119.  
  120.                         ; Calculate Minutes
  121.                         ; -----------------
  122.  
  123.         Lodsb                ; First 'minutes' byte
  124.         Call    NumberTrans        ; Translate it
  125.  
  126.         IMul    AX, 10            ; Multiply by 10
  127.         Mov    AH, AL            ; And save in AH
  128.  
  129.         Lodsb                ; Second 'minutes' byte
  130.         Call    NumberTrans        ; Translate it
  131.  
  132.         Add    AL, AH            ; Add the two
  133.         Cmp    AL, 60            ; Check if minutes > 60
  134.         Jae    ParamError        ; Another bizarre clock
  135.  
  136.         Sub    AH, AH            ; Zero out AH
  137.         Add    DX, AX            ; Parameter time in minutes
  138.  
  139.         Jmp    Short GetCurrentTime    ; All done with parsing
  140.  
  141. ; -----------------------------------------------------
  142. ;  Display 'syntax' message if an error is encountered
  143. ; -----------------------------------------------------
  144.  
  145. ParamError:    Push    ES            ; Restore DS to
  146.         Pop    DS            ;   data segment
  147.  
  148.         Mov    CX, SyntaxMsgLen    ; Length of text
  149.  
  150. WriteSyntaxMsg:    Push    1            ; Handle is standard error
  151.         Push    DS            ; Segment of text
  152.         Push    Offset SyntaxMsg    ; Offset of text
  153.         Push    CX            ; Length of text
  154.         Push    DS            ; Segment of bytes written
  155.         Push    Offset BytesWritten    ; Offset of bytes written
  156.         Call    DosWrite        ; Write the error message
  157.  
  158.         Cmp    CX, SyntaxMsgLen2    ; Check if second time through
  159.         Jz    EndPopup        ; If so, wait for keystroke
  160.  
  161.         Or    AX, AX            ; If no error, simply exit
  162.         Jz    ErrorExit
  163.  
  164.         Push    DS            ; Segment of PopupFlag
  165.         Push    Offset PopupFlag    ; Offset of PopupFlag
  166.         Push    0            ; Video handle always zero
  167.         Call    VioPopUp        ; Popup on screen
  168.  
  169.         Mov    CX, SyntaxMsgLen2    ; Text length for popup version
  170.         Jmp    WriteSyntaxMsg        ; Go to it
  171.  
  172. EndPopup:    Push    DS            ; Segment of KeyData struc
  173.         Push    Offset KeyData        ; Offset of KeyData struc
  174.         Push    0            ; Wait for keystroke
  175.         Push    0            ; Keyboard handle
  176.         Call    KbdCharIn        ; Fetch a key
  177.  
  178.         Push    0            ; Video handle
  179.         Call    VioEndPopUp        ; End the popup
  180.  
  181. ErrorExit:    Push    1            ; Terminate all threads
  182.         Push    1            ; Return error code of 1
  183.         Call    DosExit            ; And exit
  184. ; ---------------------------------------------------------------------
  185. ;  NumberTrans Subroutine -- Translates ASCII to Hex (CY set if error)
  186. ; ---------------------------------------------------------------------    
  187.  
  188. NumberTrans:    Sub    AL, '0'            ; ASCII to hex
  189.         Jc    ParamError        ; Error if under 0
  190.  
  191.         Cmp    AL, 9            ; Also error if over 9
  192.         Ja    ParamError
  193.  
  194. BadNumberTrans:    Ret
  195.  
  196. ; ---------------------------------------------------------
  197. ;  Get current time, calculate difference, and go to sleep
  198. ; ---------------------------------------------------------
  199.  
  200. GetCurrentTime:    Push    ES            ; Restore DS to data segment
  201.         Pop    DS 
  202.  
  203.         Push    DS            ; Push segment address
  204.         Push    Offset DateTime        ; Push offset of structure
  205.         Call    DosGetDateTime        ; Get current date and time
  206.  
  207.         Mov    AL, DateTime.hour    ; AL is current hour
  208.         Sub    AH, AH            ; Zero out top byte
  209.         IMul    AX, 60            ; AX is minutes since midnight
  210.         Add    AL, DateTime.minutes    ; Add the current minutes
  211.         Adc    AH, 0            ; And carry into top byte
  212.  
  213.         Xchg    AX, DX            ; Subtract parameter time
  214.         Sub    AX, DX            ;   from current time
  215.         Jnc    DifferenceOK        ; OK if both after midnight
  216.  
  217.         Add    AX, 24 * 60        ; Otherwise add whole day
  218.  
  219. DifferenceOK:    Mov    DX, 60 * 1000        ; Milliseconds in 1 minute
  220.         Mul    DX            ; DX:AX = interval in msec
  221.  
  222.         Push    DX            ; Push high word
  223.         Push    AX            ; Push low word
  224.         Call    DosSleep        ; And take a long long nap
  225.  
  226. ; -----------------------------------------------------
  227. ;  On return from DosSleep, start beeping and flashing
  228. ; -----------------------------------------------------
  229.  
  230.         Push    DS            ; Segment of flag
  231.         Push    Offset PopupFlag    ; Offset of flag
  232.         Push    0            ; Video handle always 0
  233.         Call    VioPopUp        ; Pop up!
  234.  
  235.         Mov    AX, 80            ; 80 columns across screen
  236.         Sub    AX, WakeupMsgLen    ; Less the length of message        Shr    AX, 1            ; Divide by two for margin
  237.  
  238.         Push    12            ; Row (near the center)
  239.         Push    AX            ; Column to center text
  240.         Push    0            ; Video handle
  241.         Call    VioSetCurPos        ; Set the cursor
  242.         
  243.         Push    DS            ; Segment of message
  244.         Push    Offset WakeupMsg    ; Offset of message
  245.         Push    WakeupMsgLen        ; Length of message
  246.         Push    0            ; Darn video handle again
  247.         Call    VioWrtTTY        ; Write it out
  248.  
  249.         Push    0            ; Flush keyboard buffer
  250.         Call    KbdFlushBuffer        ;   in case user is typing
  251.  
  252. FlasherLoop:    Mov    AX, 0            ; Indicates 1st attribute
  253.         Mov    BX, 512            ; One alternating tone
  254.         Mov    DX, 1024        ; Second alternating tone
  255.         Call    RingBell        ; Start it going
  256.  
  257.         Mov    AX, 1            ; Second attribute
  258.         Mov    BX, 1024        ; One alternating tone
  259.         Mov    DX, 2048        ; Second alternating tone
  260.         Call    RingBell        ; Do it again
  261.  
  262.         Push    DS            ; Segment of KeyData struc
  263.         Push    Offset KeyData        ; Offset of KeyData struc
  264.         Push    1            ; Do not wait for keystroke
  265.         Push    0            ; Keyboard handle
  266.         Call    KbdCharIn        ; Fetch a key
  267.  
  268.         Mov    AL, KeyData.char_code    ; Check if character and scn
  269.         Or    AL, KeyData.scan_code    ;   code are both zero
  270.         Jz    FlasherLoop        ; If so, no key, so continue
  271.         
  272.         Push    0            ; Video handle
  273.         Call    VioEndPopUp        ; End the popup
  274.  
  275.         Push    1            ; Terminate normally
  276.         Push    0            ; With return code for success
  277.         Call    DosExit
  278.  
  279. ; ---------------------------------------------------------------------
  280. ;  RingBell Subroutine -- Sets Attribute from AX, Beeps with BX and DX
  281. ; ---------------------------------------------------------------------
  282.  
  283. RingBell:    Add    AX, Offset Attribute    ; Attribute for screen
  284.  
  285.         Push    DS            ; Segment of attribute
  286.         Push    AX            ; Offset of attribute
  287.         Push    25 * 80            ; Number of attributes
  288.         Push    0            ; Starting row
  289.         Push    0            ; Starting column        Push    0            ; Video handle
  290.         Call    VioWrtNAttr        ; Write the attribute
  291.  
  292.         Mov    CX, 10            ; Do beeps ten times
  293.  
  294. RingBell1:    Push    BX            ; Frequency
  295.         Push    50            ; Duration
  296.         Call    DosBeep            ; Beep
  297.  
  298.         Push    DX            ; Frequency 
  299.         Push    50            ; Duration
  300.         Call    DosBeep            ; Beep
  301.  
  302.         Loop    RingBell1        ; Loop around
  303.         Ret
  304.  
  305.         END    Entry
  306.