home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -coverdisks- / 112a / gurulog / src / alertd.asm next >
Assembly Source File  |  1998-05-02  |  3KB  |  157 lines

  1. ; $VER: alertd.asm 1.1 (03.04.98)
  2. ; by Kyzer/CSG
  3. ; usage: alertd <command to run when an alert occurs>
  4. ; remove with ctrl-c
  5.  
  6.     include    dos/dos.i
  7.     include    exec/libraries.i
  8.     include    exec/nodes.i
  9.     include    exec/ports.i
  10.     include    lvo/exec_lib.i
  11.     include    lvo/dos_lib.i
  12.  
  13. ; A3 = myport (sigtask/sigbit)
  14. ; A4 = command line
  15. ; A5 = dosbase
  16. ; A6 = execbase
  17. ; D7 = sigbit
  18.  
  19.     move.l    4.w,a6            ; A6 = execbase
  20.     cmp.w    #36,LIB_VERSION(a6)    ; ensure 2.0+
  21.     bcs    .quit
  22.  
  23. ; prepare args
  24.     move.l    a0,a4            ; A4 = command line
  25.     subq.l    #1,d0
  26.     beq    .quit            ; quit if no command
  27.     clr.b    0(a4,d0.w)        ; null-terminate cmdline
  28.  
  29. ;---------------------------------------
  30. ; If we find ourselves already installed,
  31. ; we should signal the other one of us to quit.
  32.  
  33.     jsr    _LVOForbid(a6)
  34.     lea    alertd(pc),a1
  35.     jsr    _LVOFindPort(a6)
  36.     tst.l    d0
  37.     beq.s    .begin
  38.     move.l    d0,a0
  39.     move.l    MP_SIGTASK(a0),a1
  40.     move.l    #SIGBREAKF_CTRL_C,d0
  41.     jsr    _LVOSignal(a6)
  42. .begin    jsr    _LVOPermit(a6)
  43.  
  44. ; open dos
  45.     lea    dosname(pc),a1
  46.     moveq    #36,d0
  47.     jsr    _LVOOpenLibrary(a6)
  48.     tst.l    d0
  49.     beq    .quit
  50.     move.l    d0,a5            ; A5 = dosbase
  51.  
  52.     jsr    _LVOCreateMsgPort(a6)
  53.     tst.l    d0
  54.     beq    .noport
  55.     move.l    d0,a3            ; A3 = myport
  56.     ;
  57.     move.l    MP_SIGTASK(a3),d0
  58.     lea    task(pc),a0
  59.     move.l    d0,(a0)            ; store task
  60.     ;
  61.     move.b    MP_SIGBIT(a3),d7    ; D7 = sigbit
  62.     moveq    #1,d0
  63.     asl.l    d7,d0
  64.     lea    signal(pc),a0
  65.     move.l    d0,(a0)            ; store signal
  66.     ;
  67.     lea    alertd(pc),a0
  68.     move.l    a0,LN_NAME(a3)
  69.     move.b    #-1,LN_PRI(a3)
  70.     move.l    a3,a1
  71.     jsr    _LVOAddPort(a6)        ; make port public
  72.  
  73.  
  74. ; install patch
  75.     lea    usecnt(pc),a0        ; usecnt = 0
  76.     clr.w    (a0)
  77.     jsr    _LVODisable(a6)
  78.     lea    patch(pc),a0
  79.     move.l    a0,d0
  80. .reinst    bsr.s    .setf
  81.     lea    alert(pc),a0
  82.     move.l    d0,(a0)
  83.     jsr    _LVOEnable(a6)
  84.  
  85. .main    move.l    signal(pc),d0
  86.     or.l    #SIGBREAKF_CTRL_C,d0
  87.     jsr    _LVOWait(a6)        ; wait for CTRL-C or sig from patch
  88.     move.l    d0,d4
  89.     btst    d7,d4
  90.     beq.s    .notbit            ; if it was from patch
  91.     exg    a5,a6            ; then execute command-line
  92.     move.l    a4,d1
  93.     moveq    #0,d2
  94.     moveq    #0,d3
  95.     jsr    _LVOExecute(a6)
  96.     exg    a5,a6
  97. .notbit    moveq    #SIGBREAKB_CTRL_C,d0    ; quit if it was a CTRL-C signal
  98.     btst    d0,d4
  99.     beq.s    .main
  100.  
  101. .close    exg    a5,a6            ; wait for usecnt to return to 0
  102.     moveq    #1,d1
  103.     jsr    _LVODelay(a6)
  104.     exg    a5,a6
  105.     move.w    usecnt(pc),d0
  106.     bne.s    .close
  107.  
  108. ; remove patch. if we don't remove _our_ patch, but someone else's,
  109. ; then put it back and return to the main loop again!
  110.     jsr    _LVODisable(a6)
  111.     move.l    alert(pc),d0
  112.     bsr.s    .setf
  113.     lea    patch(pc),a1
  114.     cmp.l    d0,a1
  115.     bne.s    .reinst
  116.     jsr    _LVOEnable(a6)
  117.  
  118. ; bye bye
  119.     move.l    a3,a1
  120.     jsr    _LVORemPort(a6)
  121.     move.l    a3,a0
  122.     jsr    _LVODeleteMsgPort(a6)
  123. .noport    move.l    a5,a1
  124.     jsr    _LVOCloseLibrary(a6)
  125. .quit    moveq    #0,d0
  126.     rts
  127.  
  128. ; optimisation
  129. .setf    move.w    #_LVOAlert,a0
  130.     move.l    a6,a1
  131.     jmp    _LVOSetFunction(a6)
  132.  
  133. ;--------------------------------------
  134. ; The patch on Alert() itself
  135.  
  136. patch    lea    usecnt(pc),a0
  137.     addq.w    #1,(a0)
  138.  
  139.     move.l    alert(pc),a0
  140.     jsr    (a0)            ; make the original alert
  141.     move.l    task(pc),a1
  142.     move.l    signal(pc),d0
  143.     jsr    _LVOSignal(a6)        ; signal maintask to run command
  144.  
  145.     lea    usecnt(pc),a0
  146.     subq.w    #1,(a0)
  147.     rts
  148.  
  149. usecnt    dc.w    0    ; number of tasks currently calling Alert()
  150. signal    dc.l    0    ; signal-set to send to maintask
  151. task    dc.l    0    ; maintask
  152. alert    dc.l    0    ; correct address of Alert()
  153.  
  154. dosname    dc.b    'dos.library',0
  155.     dc.b    '$VER: '
  156. alertd    dc.b    'alertd 1.1',0        ; name of public port
  157.