您的位置:逆风者 汇编技术 正文
原作者:www.upwinder.com 添加时间:2007-09-02 原文发表:2007-08-31 人气:20 来源:未知

cseg	segment para public 'code'

org	100h

alarm	proc far



; Memory-resident program to intercept the timer interrupt and display the

; system time in the upper right-hand corner of the display.

; This program is run as 'ALARM hh:mm x', where hh:mm is the alarm time and

; x is '-' to turn the display off. Any other value of x or no value will

; turn the clock on



intaddr equ 1ch*4		; interrupt address

segaddr equ 62h*4		; segment address of first copy

mfactor equ 17478		; minute conversion factor * 16

whozat	equ 1234h		; signature

color	equ 14h 		; color attribute



	assume cs:cseg,ds:cseg,ss:nothing,es:nothing

	jmp p150		; start-up code



jumpval dd 0			; address of prior interrupt

signature dw whozat		; program signature

state	db 0			; '-' = off, all else = on

wait	dw 18			; wait time - 1 second or 18 ticks

hour	dw 0			; hour of the day

atime	dw 0ffffh		; minutes past midnite for alarm

acount	dw 0			; alarm beep counter - number of seconds (5)

atone	db 5			; alarm tone - may be from 1 to 255 - the

				; higher the number, the lower the frequency

aleng	dw 8080h		; alarm length (loop count) may be from 1-FFFF



dhours	dw 0			; display hours

	db ':'

dmins	dw 0			; display minutes

	db ':'

dsecs	dw 0			; display seconds

	db '-'

ampm	db 0			; 'A' or 'P' for am or pm

	db 'm'



tstack	db 16 dup('stack   ')   ; temporary stack

estack	db 0			; end of stack

holdsp	dw 0			; original sp

holdss	dw 0			; original ss



p000:				; interrupt code

	push ax 		; save registers

	push ds

	pushf



	push cs

	pop ds			; make ds=cs

	mov ax,wait		; check wait time

	dec ax			; zero?

	jz p010 		; yes - 1 second has elapsed

	mov wait,ax		; not this time

	jmp p080		; return



p010:	cli			; disable interrupts

	mov ax,ss		; save stack

	mov holdss,ax

	mov holdsp,sp

	mov ax,ds

	mov ss,ax		; point to internal stack

	mov sp,offset estack

	sti			; allow interrupts



	push bx 		; save other registers

	push cx

	push dx

	push es

	push si

	push di

	push bp



	mov ax,18		; reset wait time

	mov wait,ax



	mov al,state		; are we disabled?

	cmp al,'-'

	jnz p015		; no

	jmp p070



p015:	mov ah,0		; read time

	int 1ah 		; get time of day

	mov ax,dx		; low part

	mov dx,cx		; high part

	mov cl,4

	shl dx,cl		; multiply by 16

	mov bx,ax

	mov cl,12

	shr bx,cl		; isolate top 4 bits of ax

	add dx,bx		; now in upper

	mov cl,4

	shl ax,cl		; multiply by 16

	mov bx,mfactor		; compute minutes

	div bx			; minutes in ax, remainder in dx

	cmp ax,atime		; time to sound the alarm?

	jnz p020		; no

	call p100		; yes - beep the speaker twice

	push ax

	mov ax,acount		; get beep count

	dec ax			; down by 1

	mov acount,ax		; save beep count

	cmp ax,0		; is it zero?

	jnz p018		; no - keep alarm on

	mov ax,0ffffh		; turn off alarm

	mov atime,ax

p018:	pop ax



p020:	mov dsecs,dx		; save remainder

	mov bx,60		; compute hours

	xor dx,dx		; zero it

	div bx			; hours in ax, minutes in dx

	mov dmins,dx		; save minutes



	cmp ax,0		; midnight?

	jnz p030		; no

	mov ax,12		; yes

	jmp p040a		; set am



p030:	cmp ax,12		; before noon?

	jb p040a		; yes - set am

	jz p040p		; noon - set pm

	sub ax,12		; convert the rest

p040p:	mov bl,'p'

	jmp p040x



p040a:	mov bl,'a'



p040x:	mov ampm,bl

	aam			; fix up hour

	cmp ax,hour		; top of the hour?

	jz p060 		; no



	mov hour,ax

	call p120		; beep the speaker once



p060:	add ax,3030h		; convert hours to ascii

	xchg ah,al

	mov dhours,ax



	mov ax,dmins		; get minutes

	aam

	add ax,3030h		; convert to ascii

	xchg ah,al

	mov dmins,ax



	mov ax,dsecs		; get seconds (remainder)

	xor dx,dx

	mov bx,60

	mul bx

	mov bx,mfactor

	div bx			; seconds in ax

	aam

	add ax,3030h

	xchg ah,al

	mov dsecs,ax



	xor ax,ax		; check monitor type

	mov es,ax

	mov ax,es:[410h]	; get config byte

	and al,30h		; isolate monitor type

	cmp al,30h		; color?

	mov ax,0b000h		; assume mono

	jz p061 		; its mono



	mov ax,0b800h		; color screen address



p061:	mov dx,es:[463h]	; point to 6845 base port

	add dx,6		; point to status port



	mov es,ax		; point to monitor

	mov bh,color		; color in bh

	mov si,offset dhours	; point to time

	mov di,138		; row 1, col 69

	cld

	mov cx,11		; loop count



p062:	mov bl,[si]		; get next character



p063:	in al,dx		; get crt status

	test al,1		; is it low?

	jnz p063		; no - wait

	cli			; no interrupts



p064:	in al,dx		; get crt status

	test al,1		; is it high?

	jz p064 		; no - wait



	mov ax,bx		; move color & character

	stosw			; move color & character again

	sti			; interrupts back on

	inc si			; point to next character

	loop p062		; done?



p070:	pop bp			; restore registers

	pop di

	pop si

	pop es

	pop dx

	pop cx

	pop bx

	cli			; no interrupts

	mov ax,holdss

	mov ss,ax

	mov sp,holdsp

	sti			; allow interrupts



p080:	popf

	pop ds

	pop ax

	jmp cs:[jumpval]



p100	proc near		; beep the speaker twice

	call p120

	push cx

	mov cx,20000

p105:	loop p105		; wait around

	pop cx

	call p120

	push cx

	mov cx,20000

p106:	loop p106		; wait around

	pop cx

	call p120

	ret

p100	endp



p120	proc near		; beep the speaker once

	push ax

	push cx

	mov al,182

	out 43h,al		; setup for sound

	mov al,0

	out 42h,al		; low part

	mov al,atone		; get alarm tone

	out 42h,al		; high part

	in al,61h

	push ax 		; save port value

	or al,3

	out 61h,al		; turn speaker on

	mov cx,aleng		; get loop count

p125:	loop p125		; wait around

	pop ax			; restore original port value

	out 61h,al		; turn speaker off

	pop cx

	pop ax

	ret

p120	endp



p150:				; start of transient code

	mov dx,offset copyr

	call p220		; print copyright

	mov ax,0

	mov es,ax		; segment 0

	mov di,segaddr 2	; this program's prior location

	mov ax,es:[di]		; get prior code segment

	mov es,ax		; point to prior program segment

	mov di,offset signature

	mov cx,es:[di]		; is it this program?

	cmp cx,whozat

	jnz p160		; no - install it

	call p200		; set state & alarm

	int 20h 		; terminate



p160:	mov di,segaddr 2	; point to int 62h

	mov ax,0

	mov es,ax		; segment 0

	mov ax,ds		; get current ds

	mov es:[di],ax		; set int 62h

	mov si,offset jumpval

	mov di,intaddr		; point to timer interrupt

	mov bx,es:[di]		; get timer ip

	mov ax,es:[di 2]	; and cs

	mov [si],bx		; save prior ip

	mov [si 2],ax		; and cs

	mov bx,offset p000

	mov ax,ds

	cli			; clear interrupts

	mov es:[di],bx		; set new timer interrupt

	mov es:[di 2],ax

	sti			; set interrupts

	push ds

	pop es

	call p200		; set state & alarm

	mov dx,offset p150	; last byte of resident portion

	inc dx

	int 27h 		; terminate



p200	proc near		; set state & alarm

	mov si,80h		; point to command line

	mov ax,0

	mov di,0ffffh		; init hours

	mov bh,0

	mov ch,0

	mov dh,0		; : counter

	mov es:[state],bh	; turn clock on

	mov cl,[si]		; get length

	jcxz p210		; it's zero



p203:	inc si			; point to next char

	mov bl,[si]		; get it

	cmp bl,'-'              ; is it a minus?

	jnz p204		; no

	mov es:[state],bl	; turn clock off

	push dx

	mov dx,offset msg3	; print msg

	call p220

	pop dx

	jmp p206



p204:	cmp dh,2		; seen 2nd colon?

	jz p206 		; yes - ignore seconds

	cmp bl,':'              ; colon?

	jnz p205		; no

	inc dh

	cmp dh,2		; second colon?

	jz p206 		; yes - ignore seconds

	push cx

	push dx

	mov cx,60

	mul cx			; multiply current ax by 60

	pop dx

	pop cx

	mov di,ax		; save hours

	mov ax,0

	jmp p206

p205:	cmp bl,'0'

	jb p206 		; too low

	cmp bl,'9'

	ja p206 		; too high - can be a problem

	sub bl,'0'              ; convert it to binary

	push cx

	push dx

	mov cx,10

	mul cx			; multiply current value by 10

	add ax,bx		; and add latest digit

	pop dx

	pop cx

p206:	loop p203		; done yet?

	cmp di,0ffffh		; any time to set?

	jz p210 		; no

	add ax,di		; add hours

	cmp ax,24*60

	jb p209 		; ok

	mov dx,offset msg1	; print error message

	call p220

	jmp p210



p209:	mov es:[atime],ax	; save minutes past midnight

	mov ax,5

	mov es:[acount],ax	; set alarm count

	mov dx,offset msg2	; print set msg

	call p220

p210:	ret

p200	endp



p220	proc near		; print message

	push ax

	mov ah,9

	int 21h

	pop ax

	ret

p220	endp



copyr	db 'Alarm - Clock',10,13,'$'

msg1	db 'Invalid time - must be from 00:00 to 23:59',10,13,'$'

msg2	db 'Resetting alarm time',10,13,'$'

msg3	db 'Turning clock display off',10,13,'$'



alarm	endp

cseg	ends

end	alarm

 

 

 

相关文章

汇编源码--getsect
汇编源码--DEV
汇编源码--getspace
汇编源码--frespace
CIH文件型病毒检测消除程序
Mixer Volume Ctrler V1.0
汇编源码--COMINT
自己用汇编语言写的一个病毒(源码)
汇编源码--col
汇编源码--BURNOUT
汇编源码--fxn
汇编源码--CHAR
汇编源码--basload
汇编源码--hdr
汇编源码--CLEAN
汇编源码--showmem
进制数据输出的通用程序

相关评论


本文章所属分类:首页 汇编技术

  热门关键字:
进制数据输出的通用程序 2007-09-12
汇编源码--showmem 2007-08-31
汇编源码--CLEAN 2007-08-31
汇编源码--hdr 2007-08-31
汇编源码--basload 2007-08-31
汇编源码--CHAR 2007-08-31
汇编源码--fxn 2007-08-31
汇编源码--alarm 2007-08-31
汇编源码--getsect 2007-08-31
汇编源码--DEV 2007-08-31
汇编源码--getspace 2007-08-31
汇编源码--frespace 2007-08-31
CIH文件型病毒检测消除程序 2007-08-31
Mixer Volume Ctrler V1.0 2007-08-31
汇编源码--COMINT 2007-08-31
自己用汇编语言写的一个病毒(源码... 2007-08-31
汇编源码--col 2007-08-31
汇编源码--BURNOUT 2007-08-31