home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 02a / pctj486.zip / SETALARM.ASM < prev    next >
Assembly Source File  |  1986-02-20  |  7KB  |  182 lines

  1. ;---------------------------------------------------------- 
  2. ; Set the PC/AT alarm to user-specified time.  Points alarm  
  3. ; vector to BEEPER procedure which remains resident. 
  4. ;----------------------------------------------------------- 
  5. ; (c) Copyright Leo J. Scanlon, 1986 
  6. .286c 
  7.  
  8. PRINT$  MACRO  STRING          ; Macro that prints a string 
  9.         LEA   DX,STRING 
  10.         MOV   AH,9 
  11.         INT   21H              ;Function 9: display string 
  12.         ENDM 
  13.  
  14. PROGRAM SEGMENT PARA PUBLIC 'CODE' 
  15.         ASSUME CS:PROGRAM,DS:PROGRAM,ES:PROGRAM,SS:PROGRAM 
  16.         ORG 100H              ;designed as .COM file 
  17.  
  18. BEGINING: 
  19.         JMP MAIN              ;jump around procs and data 
  20.  
  21. START_RESIDENT: 
  22.  
  23. BEEPER   PROC 
  24.         PUSHA               ;Save the user's registers 
  25.         MOV   CX,5          ;Beep five times 
  26. BEEP:   MOV   AL,7          ;Beep for one second 
  27.         MOV   AH,0EH 
  28.         INT   10H           ;Video EH: write char as TTY 
  29.         LOOP  BEEP 
  30.         POPA                ;Restore the registers 
  31.         IRET 
  32. BEEPER   ENDP 
  33.  
  34. END_RESIDENT: 
  35. RESIDENT_LENGTH EQU END_RESIDENT - START_RESIDENT 
  36. RESIDENT_OFFSET EQU START_RESIDENT - BEGINING + 100H 
  37.  
  38. ;----------------------------------------------------------------
  39. ; See if BEEPER proc is already resident.  Sets FIRST_TIME?=0 if 
  40. ; alarm vector 4AH points to beeper routine, else leaves it 1 
  41. ;----------------------------------------------------------------
  42. FIRST_TIME?     DB 1 
  43. CHECK_BEEPER    PROC 
  44.                 MOV AH, 35H 
  45.                 MOV AL, 4AH                   
  46.                 INT 21H       ;function 35H (get interrupt vector) 
  47.                 MOV DI,BX                    ; set up ES:DI 
  48.                 MOV SI,[RESIDENT_OFFSET]     ; address BEEPER 
  49.                                              ; with DS:SI     
  50.                 MOV CX,[RESIDENT_LENGTH]     ; set length for CMPS 
  51.                 REPE CMPSB 
  52.                 JZ ALREADY_THERE             ; ZF set means match 
  53.                 RET 
  54. ALREADY_THERE:  MOV FIRST_TIME?,0 
  55.                 RET 
  56. CHECK_BEEPER    ENDP 
  57.  
  58. ;------------------------------------------------------ 
  59. ; data area: messages, prompts, and keystroke buffer. 
  60. ;------------------------------------------------------ 
  61.  
  62. CRLF     DB   13,10,'$' 
  63. BAD_DATA DB   'Digits must be between 0 and 9',13,10,'$' 
  64. BAD_HRS  DB   'Hours must be between 0 and 23',13,10,'$' 
  65. BAD_MINS DB   'Minutes must be between 0 and 59',13,10,'$' 
  66. BAD_SECS DB   'Seconds must be between 0 and 59',13,10,'$' 
  67.  
  68. PROMPT  DB    'Set the alarm time.',13,10 
  69.         DB    'Enter values or press Enter for zero' 
  70.         DB    13,10,'$' 
  71. ASK_HRS DB    'Hour (0-23): $' 
  72. ASK_MINS DB   'Minute (0-59): $' 
  73. ASK_SECS DB   'Second (0-59): $' 
  74. USER$   DB    3,4 DUP(?)    
  75.               ; User's response in 5 byte buffer 
  76.               ; <length of buffer> <chars read> <char1> <char2> <ret> 
  77.  
  78. ;--------------------------------------------------------------- 
  79. ; GET_TIME reads up to two keys into string buffer USER$, 
  80. ; then converts them into a packed BCD number in BL. 
  81. ; If either key is invalid, it prints an error message and sets 
  82. ; CF to 1. 
  83. ;--------------------------------------------------------------- 
  84.  
  85. GET_TIME PROC 
  86.         LEA   DX,USER$     ;Read user's response 
  87.         MOV   AH,0AH 
  88.         INT   21H          ; function AH (get keyboard input) 
  89. stop1:  PRINT$  CRLF       ;Advance to next line 
  90.         CMP   USER$+1,1    ;Check key count 
  91.         JAE   CONVERT 
  92.         SUB   BL,BL         ;User pressed Enter 
  93.         RET 
  94. CONVERT: MOV  AL,USER$+2   ;Get first key 
  95.         CALL  CHECK         ;Check this character 
  96.         JC    LEAVE         ;If it is valid, 
  97.         AND   AL,0FH        ; convert it to BCD 
  98.         MOV   BL,AL 
  99.         CMP   USER$+1,2    ;Is there another key? 
  100.         JB    CLR_CF 
  101.         SHL   BL,4          ;Yes. Put first digit in high bits 
  102.         MOV   AL,USER$+3    ;Get second key 
  103.         CALL  CHECK         ;Check this character 
  104.         JC    LEAVE         ;If it is valid, 
  105.         AND   AL,0FH        ; convert it to BCD 
  106.         OR    BL,AL 
  107. CLR_CF: CLC 
  108. LEAVE:  RET 
  109. GET_TIME ENDP 
  110.  
  111. ;----------------------------------------------------------- 
  112. ; CHECK makes sure an entry value is between 0 and 
  113. ; 9.  If not, it displays an error message and sets CF to 1. 
  114. ;----------------------------------------------------------- 
  115.  
  116.  
  117. CHECK   PROC 
  118.         CMP   AL,'0'        ;If entry is < 0 
  119.         JB    ERROR 
  120.         CMP   AL,'9'        ; or > 9, 
  121.         JA    ERROR         ; print message 
  122.         CLC                 ;Otherwise, clear CF and return 
  123.         RET 
  124. ERROR:  PRINT$  BAD_DATA    ;Display error message 
  125.         STC                 ;Set CF and return 
  126.         RET 
  127. CHECK   ENDP 
  128.  
  129. MAIN    PROC NEAR 
  130.         MOV   AH,7          ;Reset the alarm 
  131.         INT   1AH           ; AT BIOS interrupt 1AH (reset alarm)
  132.         CALL  CHECK_BEEPER 
  133.         CMP   FIRST_TIME?, 1 
  134.         JNE   USER_INPUT     
  135.         MOV   AL,4AH        ;Make the 4A vector point to BEEPER 
  136.         LEA   DX,BEEPER 
  137.         MOV   AH,25H 
  138.         INT   21H           ;function 25H (set interrupt vector) 
  139.  
  140. USER_INPUT: 
  141.         PRINT$  PROMPT     ;Ask for alarm hour 
  142. HOUR:   PRINT$  ASK_HRS 
  143.         CALL  GET_TIME     ;Convert it to BCD 
  144.         JC    HOUR 
  145.         CMP   BL,23H        ;Make sure it's < 24 
  146.         JNA   HRS2CH 
  147.         PRINT$  BAD_HRS 
  148.         JMP   HOUR 
  149. HRS2CH: MOV   CH,BL         ; and put it in CH 
  150.  
  151. MIN:    PRINT$  ASK_MINS   ;Ask for alarm minutes 
  152.         CALL  GET_TIME     ;Convert it to BCD 
  153.         JC    MIN 
  154.         CMP   BL,59H        ;Make sure it's < 60 
  155.         JNA   MIN2CL 
  156.         PRINT$  BAD_MINS 
  157.         JMP   MIN 
  158. MIN2CL: MOV   CL,BL         ; and put it in CL 
  159.  
  160. SEC:    PRINT$  ASK_SECS   ;Ask for alarm seconds 
  161.         CALL  GET_TIME     ;Convert it to BCD 
  162.         JC    SEC 
  163.         CMP   BL,59H        ;Make sure it's < 60 
  164.         JNA   SEC2DH 
  165.         PRINT$  BAD_SECS 
  166.         JMP   SEC 
  167. SEC2DH: MOV   DH,BL         ; and put it in DH 
  168.         MOV   AH,6 
  169.         INT   1AH           ;AT BIOS interrupt 1AH (set alarm) 
  170.         CMP   FIRST_TIME?, 1 
  171.         JNE   CLEAR_OUT      
  172.         MOV   DX, RESIDENT_OFFSET + RESIDENT_LENGTH 
  173.                             ;first invocation - leave BEEPER resident 
  174.         INT   27H           ;interrupt 27H (terminate, stay resident) 
  175.  
  176. CLEAR_OUT: 
  177.         RET                 ;BEEPER already in place so  
  178.                             ;exit normally 
  179. MAIN    ENDP 
  180. PROGRAM ENDS 
  181.         END BEGINING 
  182.