home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 28
/
amigaformatcd28.iso
/
-coverdisks-
/
112a
/
gurulog
/
src
/
alertd.asm
next >
Wrap
Assembly Source File
|
1998-05-02
|
3KB
|
157 lines
; $VER: alertd.asm 1.1 (03.04.98)
; by Kyzer/CSG
; usage: alertd <command to run when an alert occurs>
; remove with ctrl-c
include dos/dos.i
include exec/libraries.i
include exec/nodes.i
include exec/ports.i
include lvo/exec_lib.i
include lvo/dos_lib.i
; A3 = myport (sigtask/sigbit)
; A4 = command line
; A5 = dosbase
; A6 = execbase
; D7 = sigbit
move.l 4.w,a6 ; A6 = execbase
cmp.w #36,LIB_VERSION(a6) ; ensure 2.0+
bcs .quit
; prepare args
move.l a0,a4 ; A4 = command line
subq.l #1,d0
beq .quit ; quit if no command
clr.b 0(a4,d0.w) ; null-terminate cmdline
;---------------------------------------
; If we find ourselves already installed,
; we should signal the other one of us to quit.
jsr _LVOForbid(a6)
lea alertd(pc),a1
jsr _LVOFindPort(a6)
tst.l d0
beq.s .begin
move.l d0,a0
move.l MP_SIGTASK(a0),a1
move.l #SIGBREAKF_CTRL_C,d0
jsr _LVOSignal(a6)
.begin jsr _LVOPermit(a6)
; open dos
lea dosname(pc),a1
moveq #36,d0
jsr _LVOOpenLibrary(a6)
tst.l d0
beq .quit
move.l d0,a5 ; A5 = dosbase
jsr _LVOCreateMsgPort(a6)
tst.l d0
beq .noport
move.l d0,a3 ; A3 = myport
;
move.l MP_SIGTASK(a3),d0
lea task(pc),a0
move.l d0,(a0) ; store task
;
move.b MP_SIGBIT(a3),d7 ; D7 = sigbit
moveq #1,d0
asl.l d7,d0
lea signal(pc),a0
move.l d0,(a0) ; store signal
;
lea alertd(pc),a0
move.l a0,LN_NAME(a3)
move.b #-1,LN_PRI(a3)
move.l a3,a1
jsr _LVOAddPort(a6) ; make port public
; install patch
lea usecnt(pc),a0 ; usecnt = 0
clr.w (a0)
jsr _LVODisable(a6)
lea patch(pc),a0
move.l a0,d0
.reinst bsr.s .setf
lea alert(pc),a0
move.l d0,(a0)
jsr _LVOEnable(a6)
.main move.l signal(pc),d0
or.l #SIGBREAKF_CTRL_C,d0
jsr _LVOWait(a6) ; wait for CTRL-C or sig from patch
move.l d0,d4
btst d7,d4
beq.s .notbit ; if it was from patch
exg a5,a6 ; then execute command-line
move.l a4,d1
moveq #0,d2
moveq #0,d3
jsr _LVOExecute(a6)
exg a5,a6
.notbit moveq #SIGBREAKB_CTRL_C,d0 ; quit if it was a CTRL-C signal
btst d0,d4
beq.s .main
.close exg a5,a6 ; wait for usecnt to return to 0
moveq #1,d1
jsr _LVODelay(a6)
exg a5,a6
move.w usecnt(pc),d0
bne.s .close
; remove patch. if we don't remove _our_ patch, but someone else's,
; then put it back and return to the main loop again!
jsr _LVODisable(a6)
move.l alert(pc),d0
bsr.s .setf
lea patch(pc),a1
cmp.l d0,a1
bne.s .reinst
jsr _LVOEnable(a6)
; bye bye
move.l a3,a1
jsr _LVORemPort(a6)
move.l a3,a0
jsr _LVODeleteMsgPort(a6)
.noport move.l a5,a1
jsr _LVOCloseLibrary(a6)
.quit moveq #0,d0
rts
; optimisation
.setf move.w #_LVOAlert,a0
move.l a6,a1
jmp _LVOSetFunction(a6)
;--------------------------------------
; The patch on Alert() itself
patch lea usecnt(pc),a0
addq.w #1,(a0)
move.l alert(pc),a0
jsr (a0) ; make the original alert
move.l task(pc),a1
move.l signal(pc),d0
jsr _LVOSignal(a6) ; signal maintask to run command
lea usecnt(pc),a0
subq.w #1,(a0)
rts
usecnt dc.w 0 ; number of tasks currently calling Alert()
signal dc.l 0 ; signal-set to send to maintask
task dc.l 0 ; maintask
alert dc.l 0 ; correct address of Alert()
dosname dc.b 'dos.library',0
dc.b '$VER: '
alertd dc.b 'alertd 1.1',0 ; name of public port