home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 500.lha / NoCare_v1.5 / NoCare.asm < prev    next >
Assembly Source File  |  1991-04-08  |  12KB  |  485 lines

  1. ;-----------------------------------------------------------------------------
  2. ;
  3. ; Program    : NoCare.asm V1.5
  4. ; Author     : Raymond Hoving, The Orega Programming Group Holland
  5. ; Creation Date : Wed Jan 16 19:28:28 1991
  6. ; Purpose    : A utility to speed up the workbench window environment.
  7. ; Usage        : NoCare - Starts/stops the program from a CLI/Shell.                
  8. ;
  9. ; See copyright notes in file called 'NoCare.doc'.
  10. ; Bug reports or comments to:
  11. ;
  12. ;    The Orega Programming Group Holland,
  13. ;    P.o.box 499,                Apothekersdijk 24,
  14. ;     2280 AL Rijswijk,            2312 DD Leiden,
  15. ;    The Netherlands.            The Netherlands.
  16. ;                        Phone .. - (0)71 - 14 49 71
  17. ;
  18. ; or UUCP: breemen@rulcvx.LeidenUniv.nl (shared account).
  19. ;
  20. ;-----------------------------------------------------------------------------
  21.  
  22. OPENLIB    macro                ; \1 library name.
  23.     data                ; \2 address of failure handling code.
  24. \1name    dc.b    '\1.library',0             Use 0 for \1fails.
  25.     even                 ; \3 Optional version number.
  26. \1base    ds.l    1            ;    (Default value is 33)
  27.     code                ; Registers affected d0,a1,a6.
  28.     lea.l    \1name,a1
  29.     ifne    NARG-3
  30.     move.l  #33,d0
  31.     endc
  32.     ifeq     NARG-3
  33.     move.l    #\3,d0
  34.     endc
  35.     CALL     exec,OpenLibrary
  36.     move.l    d0,\1base
  37.     ifc     '\2','0'
  38.     beq    \1fails
  39.     endc
  40.     ifnc     '\2','0'
  41.     beq    \2
  42.     endc
  43.     endm
  44.  
  45. CLOSELIB macro                ; \1 library name.
  46.     move.l    \1base,a1        ; Registers affected a1,a6.
  47.     CALL    exec,CloseLibrary
  48.     endm
  49.  
  50. CALL    macro                ; \1 library name.
  51.     ifnc    '\1','exec'        ; \2 function name.
  52.     move.l    \1base,a6        ; Registers affected a6.
  53.     endc
  54.     ifc    '\1','exec'
  55.     move.l    _SysBase,a6
  56.     endc
  57.     jsr    _LVO\2(a6)
  58.     endm
  59.  
  60. CALLR    macro                ; \1 function name.
  61.     jsr    _LVO\1(a6)        ; No registers affected.
  62.     endm    
  63.  
  64. STANDARDOUTPUT macro            ; Init of stdout, used by PRINT etc.
  65.     data
  66. stdout    ds.l    1
  67.     code
  68.     CALL dos,Output
  69.     move.l    d0,stdout
  70.     endm
  71.  
  72. PRINT    macro                 ; Prints string at location \1
  73.     move.l    stdout,d1        ; with lenght \2. No automatic
  74.     move.l    #\1,d2            ; linefeed.
  75.     move.l    #\2,d3
  76.     CALL dos,Write
  77.     endm
  78.  
  79. _LVOOpenLibrary        equ    -552    ; Library vector offsets.
  80. _LVOCloseLibrary    equ    -414    ; No need to link with amiga.lib.
  81. _LVOOutput        equ    -60
  82. _LVOWrite        equ    -48
  83. _LVOAllocSignal        equ    -330
  84. _LVOFreeSignal        equ    -336
  85. _LVOFindTask        equ    -294
  86. _LVOFindPort        equ    -390
  87. _LVOAddPort        equ    -354
  88. _LVORemPort        equ    -360
  89. _LVOAllocEntry        equ    -222
  90. _LVOWaitPort        equ    -384
  91. _LVOGetMsg        equ    -372
  92. _LVOPutMsg        equ    -366
  93. _LVOReplyMsg        equ    -378
  94. _LVOSetFunction        equ    -420
  95. _LVOForbid        equ    -132
  96. _LVOPermit        equ    -138
  97. _LVOCopyMem        equ    -624
  98. _LVOAddTail        equ    -246
  99. _LVOAddTask        equ    -282
  100. _LVORemTask        equ    -288
  101. _LVOOpenWindow        equ    -204
  102. _SysBase        equ    $4
  103.  
  104.  
  105.     include exec/exec.i
  106.     include intuition/intuition.i
  107.     include    intuition/screens.i
  108.  
  109. REFRESHBIT0    equ    $06
  110. REFRESHBIT1    equ    $07    ; Bits in the nw_Flags field.
  111.         
  112. STACKSIZE    equ    200    ; Stack size for the NoCare task.
  113.  
  114. MN_CONTENTS    equ    MN_SIZE
  115. REPLY        equ    $0
  116. FAILURE        equ    $1
  117. SUCCESS        equ    $2
  118. REMOVE        equ    $3    ; Inter-task communication defenitions.
  119.  
  120.     code
  121.  
  122. ; Open dos.library and print message.
  123.  
  124.     OPENLIB dos,0
  125.     STANDARDOUTPUT
  126.     PRINT    mess1,mess2-mess1
  127.  
  128. ; Create a message port for communication with the NoCare task:
  129.  
  130.     move.l    #-1,d0
  131.     CALL    exec,AllocSignal
  132.     move.b    d0,signal1
  133.     bmi    signal1fails        ; Allocate a signal.
  134.     sub.l    a1,a1
  135.     CALLR    FindTask
  136.     lea.l    port1,a1
  137.     move.l    d0,MP_SIGTASK(a1)    ; Link this task into messageport.
  138.     move.b    signal1,MP_SIGBIT(a1)    ; Link allocated signal into port.
  139.     CALLR    AddPort            ; Make the port a public one.
  140.  
  141. ; Is NoCare active already?
  142.  
  143.     CALLR    Forbid
  144.     lea.l    port2name,a1        ; Try to find NoCare2.Orega port.
  145.     CALLR    FindPort
  146.     move.l    d0,d6
  147.     CALLR    Permit
  148.     tst.l    d6
  149.     bne    sendremovemessage
  150.  
  151. ; The NoCare2.Orega port has not been found, so start the NoCare task:
  152. ; First allocate memory for the task structure, the stack and a safe
  153. ; place for the PC-relative code of the NoCare task.
  154.  
  155.     lea.l    memlist1,a0
  156.     CALLR    AllocEntry
  157.     bclr.l    #31,d0
  158.     bne    allocerror        ; Not enough memory!
  159.     move.l    d0,a5            ; Remember address in a5.
  160.  
  161. ; Then copy the PC-relative taskcode to the safe place:
  162.  
  163.     move.l    LN_SIZE+10(a5),a1    ; Get pointer to allocated memory.
  164.     lea.l    codestart,a0
  165.     move.l    #codeend-codestart,d0    
  166.     CALLR    CopyMem
  167.     
  168. ; Then create the new task (has no name yet):
  169.  
  170.     move.l    LN_SIZE+2(a5),a0    ; Get pointer to allocated memory.
  171.  
  172. ; Link stack, task structure and code area into task's memlist:
  173.  
  174.     lea.l    TC_MEMENTRY(a0),a0    ; Get pointer to task's memlist.
  175.     move.b    #NT_MEMORY,LN_TYPE(a0)
  176.     move.l  a0,(a0)
  177.     addq.l  #LH_TAIL,(a0)
  178.     clr.l   LH_TAIL(a0)        ; Initialise list structure.
  179.     move.l  a0,(LH_TAIL+LN_PRED)(a0)
  180.     
  181.     move.l    a5,a1
  182.     CALLR    AddTail            ; Add node to memlist.
  183.  
  184.     move.l    LN_SIZE+2(a5),d0
  185.     move.l    d0,a1
  186.     add.l    #TC_SIZE,d0
  187.     move.l    d0,TC_SPLOWER(a1)    ; Lower stack boundary,
  188.     add.l    #STACKSIZE,d0
  189.     move.l    d0,TC_SPUPPER(a1)    ; Upper stack boundary.
  190.     move.l    d0,TC_SPREG(a1)        ; Initial stack pointer.
  191.     move.b    #NT_TASK,LN_TYPE(a1)    ; Node type.
  192.     move.l    LN_SIZE+10(a5),a2    ; Initial PC of NoCare task.
  193.     sub.l    a3,a3
  194.     CALLR    AddTask            ; Lets's go!
  195.  
  196. RemTask
  197.  
  198. ; The NoCare task has been launched, now wait for the startup message:
  199.  
  200. getmsgloop1
  201.     lea.l    port1,a0
  202.     CALLR    WaitPort        ; Wait for a message.
  203.     lea.l    port1,a0
  204.     CALLR    GetMsg            ; Get the new message.
  205.     move.l    d0,a1
  206.     move.w    MN_CONTENTS(a1),d6    ; Save the important field.
  207.     move.w    #REPLY,MN_CONTENTS(a1)    ; Mark as a replied message.
  208.     CALLR    ReplyMsg        ; Quickly reply message.
  209.  
  210. ; Examine the startup message now:
  211.  
  212.     cmp.w    #FAILURE,d6
  213.     beq.s    installfailed
  214.     cmp.w    #SUCCESS,d6
  215.     bne.s    getmsgloop1        ; Should never execute this.
  216.     PRINT    mess2,mess3-mess2    ; 'Installed.'
  217.     bra    ex1
  218. installfailed
  219.     PRINT    mess4,mess5-mess4    ; 'Could not install.'
  220.     bra    ex1
  221.  
  222. ; Send a message to the messageport of the NoCare task.
  223. ; This informs the NoCare task to remove the OpenWindow patch.
  224. ; The address of the messageport is in d6:
  225.  
  226. sendremovemessage
  227.     lea.l    message1,a1
  228.     move.w    #REMOVE,MN_CONTENTS(a1)
  229.     move.l    d6,a0            ; Destination port.
  230.     CALLR    PutMsg
  231. getmsgloop2
  232.     lea.l    port1,a0
  233.     CALLR    WaitPort        ; Wait for reply.
  234.     lea.l    port1,a0
  235.     CALLR    GetMsg
  236.     move.l    d0,a0
  237.     move.w    MN_CONTENTS(a0),d0
  238.  
  239. ; We asked the NoCare task to remove itself (and of course the
  240. ; OpenWindow patch). Examine the reply of the NoCare task:
  241.  
  242.     cmp.w    #FAILURE,d0
  243.     beq.s    remerror
  244.     cmp.w    #SUCCESS,d0
  245.     bne.s    getmsgloop2        ; Should never execute this.
  246.     PRINT    mess3,mess4-mess3    ; 'Removed.'
  247.     bra.s    ex1
  248. remerror
  249.     PRINT    mess5,mess6-mess5    ; 'Could not remove.'
  250.     bra.s    ex1
  251.  
  252. ; Error handling code:
  253.  
  254. signal1fails
  255.     PRINT    mess6,mess7-mess6
  256.     bra.s    ex0
  257. allocerror
  258.     PRINT    mess6,mess7-mess6
  259.  
  260. ; Cleanup code follows:
  261.  
  262. ex1    lea.l    port1,a1
  263.     CALL    exec,RemPort
  264.     clr.l    d0
  265.     move.b    signal1,d0        ; Free signal.
  266.     CALLR    FreeSignal
  267. ex0    CLOSELIB dos
  268. dosfails
  269.     rts
  270.  
  271.     data
  272.  
  273. message1    dc.l    0,0        ; ln_succ, ln_pred
  274.         dc.b    NT_MESSAGE,0    ; ln_type, ln_pri
  275.         dc.l    0        ; ln_name
  276.         dc.l    port1        ; mn_replyport
  277.         dc.w    MN_SIZE+2    ; mn_length
  278.         dc.w    0        ; mn_contents
  279.  
  280. port1        dc.l    0,0        ; ln_succ, ln_pred
  281.         dc.b    NT_MSGPORT,1    ; ln_type, ln_pri
  282.         dc.l    port1name    ; ln_name
  283.         dc.b    PA_SIGNAL,0    ; mp_flags, mp_sigbit
  284.         dc.l    0        ; mp_sigtask
  285.         dc.l    0,0,0        ; lh_head, lh_tail, lh_tailpred
  286.         dc.b    NT_MESSAGE,0    ; lh_type, lh_pad
  287.  
  288. memlist1    dc.l    0,0        ; ln_succ, ln_pred
  289.         dc.b    NT_MEMORY,0    ; ln_type, ln_pri
  290.         dc.l    0        ; ln_name
  291.         dc.w    2        ; Numer of entries.
  292.         dc.l    MEMF_PUBLIC!MEMF_CLEAR
  293.         dc.l    STACKSIZE+TC_SIZE
  294.         dc.l    MEMF_PUBLIC
  295.         dc.l    codeend-codestart
  296.  
  297. signal1        ds.l    1
  298. port1name    dc.b    'NoCare1.Orega',0
  299. port2name    dc.b    'NoCare2.Orega',0
  300. mess1        dc.b    $1b,'[33mNoCare V1.5',$1b,'[0m by Raymond Hoving,'
  301.         dc.b    ' THE OREGA PROGRAMMING GROUP HOLLAND.',$a
  302. mess2        dc.b    'OpenWindow() patch installed.',$a
  303. mess3        dc.b    'OpenWindow() patch removed.',$a
  304. mess4        dc.b    'ERROR: Could not install.',$a
  305. mess5        dc.b    'ERROR: Could not remove.',$a
  306. mess6        dc.b    'ERROR: Out of memory/signals',$a
  307. mess7
  308.  
  309. ;-----------------------------------------------------------------------------
  310. ; Now follows the code of the NoCare task. This code is PC-relative.
  311. ; First we give this task a name:
  312.  
  313.     code
  314.  
  315. codestart
  316.     sub.l    a1,a1
  317.     CALL    exec,FindTask
  318.     move.l    d0,a0
  319.     lea.l    taskname(PC),a1
  320.     move.l    a1,LN_NAME(a0)
  321.  
  322. ; Open intuition.library:
  323.  
  324.     lea.l    intuitionname(PC),a1
  325.     clr.l    d0
  326.     CALLR    OpenLibrary
  327.     lea.l    intuitionbase(PC),a2
  328.     move.l    d0,(a2)
  329. ;    beq.s    intuitionfails        ; Any version will do.
  330.  
  331. ; Then patch the OpenWindow() function:
  332.  
  333.     move.l    d0,a1
  334.     move.w    #_LVOOpenWindow,a0
  335.     lea.l    newopenwindow(PC),a2
  336.     move.l    a2,d0
  337.     CALLR    SetFunction
  338.     lea.l    oldopenwindow(PC),a2
  339.     move.l    d0,(a2)
  340.  
  341. ; Create a message port (called NoCare2.Orega)
  342.  
  343.     move.l    #-1,d0
  344.     CALLR    AllocSignal
  345. ;    bmi    signal2fails        ; It's my task!
  346.     lea.l    signal2(PC),a2
  347.     move.b    d0,(a2)
  348.     sub.l    a1,a1
  349.     CALLR    FindTask
  350.     lea.l    port2(PC),a1
  351.     move.l    d0,MP_SIGTASK(a1)
  352.     lea.l    port2name2(PC),a0
  353.     move.l    a0,LN_NAME(a1)
  354.     move.b    signal2(PC),MP_SIGBIT(a1)
  355.     CALLR    AddPort            ; Add port to system.
  356.  
  357. ; Now send a message to our parent task, that NoCare is installed
  358. ; without problems:
  359.     
  360.     CALLR    Forbid
  361.     lea.l    port1name2(PC),a1    ; Try to find NoCare1.Orega port.
  362.     CALLR    FindPort
  363.     move.l    d0,d6            ; Remember port in d6.
  364.     CALLR    Permit
  365.     tst.l    d6
  366. ;    beq    port1gone        ; Impossible situation!
  367.  
  368.     lea.l    port2(PC),a0
  369.     lea.l    message2(PC),a1
  370.     move.l    a0,MN_REPLYPORT(a1)
  371.     move.w    #SUCCESS,MN_CONTENTS(a1)
  372.     move.l    d6,a0            ; Destination port.
  373.     CALLR    PutMsg
  374.  
  375. ; Then wait for the REPLY message or the REMOVE message:
  376.  
  377. getmsgloop3
  378.     lea.l    port2(PC),a0
  379.     CALLR    WaitPort        ; Wait for message.
  380.     lea.l    port2(PC),a0
  381.     CALLR    GetMsg
  382.     move.l    d0,a0
  383.     cmp.w    #REMOVE,MN_CONTENTS(a0)
  384.     bne.s    getmsgloop3        ; It's the REPLY message.
  385.     move.l    d0,a5            ; Remember this message.
  386.  
  387. ; So the user wants to terminate NoCare.
  388. ; First test if someone else patched our patch.
  389.  
  390.     CALLR    Forbid
  391.     move.l    intuitionbase(PC),a3
  392.     move.l    _LVOOpenWindow+2(a3),a3    ; Get OpenWindow vector.
  393.     lea.l    newopenwindow(PC),a4
  394.     cmp.l    a3,a4
  395.     bne.s    removeerror
  396.  
  397. ; Now we restore the old OpenWindow vector:
  398.  
  399.     move.l    oldopenwindow(PC),d0    ; Pointer to original code.
  400.     move.l    intuitionbase(PC),a1
  401.     move.w    #_LVOOpenWindow,a0
  402.     CALLR    SetFunction
  403.     CALLR    Permit
  404.  
  405. ; Then we remove the messageport and free the signal bit:
  406.  
  407.     lea.l    port2(PC),a1
  408.     CALLR    RemPort
  409.     clr.l    d0
  410.     move.b    signal2(PC),d0
  411.     CALLR    FreeSignal        ; Just to be nice.
  412.  
  413. ; Reply the REMOVE message:
  414.  
  415.     move.l    a5,a1            ; Pointer to the REMOVE message.
  416.     move.w    #SUCCESS,MN_CONTENTS(a1)
  417.     CALLR    ReplyMsg
  418.  
  419. ; Close intuition.library:
  420.  
  421.     move.l    intuitionbase(PC),a1
  422.     CALLR    CloseLibrary
  423.  
  424. ; Then call exec's standard task finalizer. The task structure,
  425. ; it's stack and the safeplace-area will be freed.
  426.  
  427.     sub.l    a1,a1
  428.     CALLR    RemTask            ; End of NoCare task.
  429.  
  430. ;-----------------------------------------------------------------------------
  431. ; When NoCare could not be removed, we reply with a failure type message.
  432.  
  433. removeerror
  434.     CALLR    Permit
  435.     move.l    a5,a1
  436.     move.w    #FAILURE,MN_CONTENTS(a1)
  437.     CALLR    ReplyMsg
  438.     bra    getmsgloop3        ; Wait for another try...
  439.  
  440. ;-----------------------------------------------------------------------------
  441. ; As OpenWindow() is called, then a0 points to a NewWindow structure.
  442. ; We patch a bit in the nw_Flags field and than jump to the original
  443. ; OpenWindow() code.
  444.  
  445. newopenwindow
  446.     cmp.w    #WBENCHSCREEN,nw_Type(a0)
  447.     bne.s    dontchange
  448.     move.l    nw_Flags(a0),d0
  449.     bclr    #REFRESHBIT0,d0        ; We don't want SIMPLE_REFRESH ones.
  450.     move.l    d0,nw_Flags(a0)
  451. dontchange
  452.     move.l    oldopenwindow(PC),a1
  453.     jmp    (a1)            ; Jump to original code.
  454.  
  455. ;-----------------------------------------------------------------------------
  456.  
  457. message2    dc.l    0,0        ; ln_succ, ln_pred
  458.         dc.b    NT_MESSAGE,0    ; ln_type, ln_pri
  459.         dc.l    0        ; ln_name
  460.         dc.l    0        ; mn_replyport
  461.         dc.w    MN_SIZE+2    ; mn_length
  462.         dc.w    0        ; mn_contents
  463.  
  464. port2        dc.l    0,0        ; ln_succ, ln_pred
  465.         dc.b    NT_MSGPORT,1    ; ln_type, ln_pri
  466.         dc.l    0        ; ln_name
  467.         dc.b    PA_SIGNAL,0    ; mp_flags, mp_sigbit
  468.         dc.l    0        ; mp_sigtask
  469.         dc.l    0,0,0        ; lh_head, lh_tail, lh_tailpred
  470.         dc.b    NT_MESSAGE,0    ; lh_type, lh_pad
  471.  
  472. oldopenwindow    ds.l    1
  473. signal2        ds.l    1
  474. intuitionbase    ds.l    1
  475. taskname    dc.b    'NoCareTask.Orega',0
  476. port1name2    dc.b    'NoCare1.Orega',0
  477. port2name2    dc.b    'NoCare2.Orega',0
  478. intuitionname    dc.b    'intuition.library',0
  479.  
  480. codeend
  481.  
  482.     end
  483.  
  484. ;-----------------------------------------------------------------------------
  485.