
TITLE SETALARM -- Set the alarm
;set the alarm based on user values
      extrn gensound:far
stack segment para stack 'stack'
	 db 64 dup('stack...')
stack ends
;--------------------------------------------------
dseg segment para public 'data'
bad_data  db 'Digits must be between 0 and 9'
	  db 13,10,'$'
bad_hrs   db 'Hours must be between 0 and 23'
	  db 13,10,'$'
bad_mins  db 'Minutes must be between 0 and 59'
	  db 13,10,'$'
bad_secs  db 'seconds must be between 0 and 59'
	  db 13,10,'$'
crlf	  db 13,10,'$'
prompt    db 'Set the alarm time.',13,10
	  db 'Enter values or press enter for'
	  db 'zero',13,10,'$'
ask_hrs	  db 'Hour (0 - 23):$'
ask_mins  db 'Minute (0 - 59):$'
ask_secs  db 'Second (0 - 59):$'
user$	  db 3,3 dup(?)		;user's response
dseg ends
;-------------------------------------------------
cseg segment para public 'code'
	assume cs:cseg, ss:stack, ds:dseg
entry proc far
	push	ds	      ;set up return address
	sub	ax,ax
	push	ax

	mov	al,4ah	      ;read the type 4A vector
	mov	ah,35h
	int	21h
	push	es	      ;save it on the stack
	push	bx

	mov	ah,7	      ;reset the alarm
	int	1ah

	mov	al,4ah        ;make the 4A vector  
			      ;  point to alarm
	mov	dx,seg alarm
	mov	ds,dx
	mov	dx,offset alarm
	mov	ah,25h
	int	21h

	mov	ax,dseg	      ;point to dseg segment
	mov	ds,ax
Š
	lea	dx,prompt     ;ask for alarm time
	mov	ah,9
	int	21h

hour:	lea	dx,ask_hrs    ;ask for alarm hour
	mov	ah,9
	int	21h
	call	get_time      ;convert it to BCD
	jc	hour
	cmp	bl,23h	      ;make sure it's < 24
	jna	hrs2ch
	lea	dx,bad_hrs
	mov	ah,9
	int	21h
	jmp	hour
hrs2ch:	mov	ch,bl	      ;and put it in CH
min:	lea	dx,ask_mins   ;ask for alarm minutes
	mov	ah,9
	int	21h
	call	 get_time     ;convert it to BCD
	jc	min
	cmp	bl,59h	      ;make sure it's < 60
	jna	min2cl
	lea	dx,bad_mins
	mov	ah,9
	int	21h
	jmp	min
min2cl:	mov	cl,bl	      ;and put it in CL
sec:	lea	dx,ask_secs   ;ask for alarm
	mov	ah,9	      ;  seconds
	int	21h
	call	get_time      ;convert it to BCD
	jc	sec
	cmp	bl,59h	      ;make sure it's < 60
	jna	sec2dh
	lea	dx,bad_secs
	mov	ah,9
	int	21h
	jmp	sec
sec2dh:	mov	dh,bl	      ;and put it in DH

	mov	ah,6	      ;set the alarm
	int	1ah

	mov	dx,32000
mainp1:	mov	cx,500
mainp2:	loop	mainp2
	dec	dx
	jne	mainp1
res:	pop	dx	      ;restore the 4ah vector
	pop	ds
	mov	al,4ah
	mov	ah,35h
	int	21h
	ret		      ;and exit
entry endp
;------------------------------------------------------
;following is the alarm routine
alarm proc 
	push	ax	      ;save the caller's reg.
	push	bx
	push	di
	sti
	mov	ah,2
	mov	dl,'!'
	int	21h
	mov	di,1000	      ;frequency
	mov	bx,100	      ;beep for one second
	call	gensound
	pop	di
	pop	bx
	pop	ax
	iret
alarm endp
;------------------------------------------------------
;This procedure reads up to two keys into
;  string buffer user$,then cinverts them into
;  a packed BCD number in BL
;  if either key is invalid, it prints an
;  error message and set CF to 1
get_time proc 
	lea	dx,user$      ;input user's response
	mov	ah,0ah
	int	21h
	lea	dx,crlf       ;adrance to next line
	mov	ah,9
	int	21h
	cmp	user$+1,1     ;check character count
	jae	convert
	sub	bl,bl	      ;user pressed enter
	ret
convert:mov	cl,4
	mov	al,user$+2    ;get first character
	jc	leave	      ;if it is valid
	and	al,0fh	      ;convert it to BCD
	mov	bl,al
	cmp	user$+1,2     ;is there another char?
	jb	clr_cf
	shl	bl,cl	      ;yes put first digit
			      ;  in high bits
	mov	al,user$+3    ;get second character
	call	check	      ;check this character
	jc	leave	      ;if it is valid
	and	al,0fh	      ;convert it to BCD
	or	bl,al
clr_cf: clc
leave:	ret
get_time endp
;------------------------------------------------------
;this procedure checks whether an entry
;  value is between 0 and 9,if not ,it 
;  displays an error message 
;  and sets CF to 1
check proc 
	cmp	al,'0'	      ;if entry is < 0
	jb	error
	cmp	al,'9'        ;or > 9
	ja	error	      ;print message
	clc		      ;otherwise,clear CF
	ret		      ; and return
error:	lea	dx,bad_data   ;display error message
	mov	ah,9
	int	21h
	stc		      ;set CF
	ret		      ;and return
check endp
cseg  ends
;--------------------------------------------------
      end entry
 