home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / aros / source / exec / internal / m68k / dispatch.asm < prev    next >
Encoding:
Assembly Source File  |  1996-07-16  |  4.8 KB  |  147 lines

  1. |*****************************************************************************
  2. |
  3. |   NAME
  4. |
  5. |    void Dispatch (
  6. |
  7. |   SYNOPSIS
  8. |    void)
  9. |
  10. |   FUNCTION
  11. |    This function switches between the task in SysBase->ThisTask and
  12. |    the first task in the ready list. Is must be called from supervisor
  13. |    mode with all registers set to the values of the underlying user
  14. |    context and sp pointing to the normal exception frame (just as if
  15. |    it was a routine in one of the interrupt vectors).
  16. |
  17. |    SysBase->IDNestCnt is moved to and from the task structures and
  18. |    the interrupt control is prepared accordingly. The routines in
  19. |    task->tc_Launch and task->tc_Switch are called if necessary and
  20. |    a task exception for the new task is raised if TF_EXCEPT is set.
  21. |
  22. |    If the ready list is empty this function waits (with interrupts
  23. |    enabled) until a task is willing to run.
  24. |
  25. |   INPUTS
  26. |
  27. |   RESULT
  28. |
  29. |   NOTES
  30. |    If the current task (when calling this function) is not part of
  31. |    one of the two task lists it gets lost.
  32. |
  33. |    This function is for internal exec use only.
  34. |
  35. |    This function is processor dependant.
  36. |
  37. |   EXAMPLE
  38. |
  39. |   BUGS
  40. |    This function currently doesn't read *(struct ExecBase **)4 to get
  41. |    SysBase and thus works only from Switch(). But it makes it usable
  42. |    for link libraries.
  43. |
  44. |   SEE ALSO
  45. |
  46. |   INTERNALS
  47. |    For the task lists the following conditions must always be true as
  48. |    long as SysBase->IDNestCnt>=0. Changes are legal with interrupts
  49. |    Disable()d only:
  50. |
  51. |    * A task is in state TS_WAIT if and only if it is part of the waiting
  52. |      list.
  53. |    * It is in state TS_READY if and only if it is part of the ready list.
  54. |    * SysBase->ThisTask always points to a legal task structure.
  55. |    * In normal user context SysBase->ThisTask->tc_State is TS_RUN.
  56. |      There are two possible exceptions from this rule:
  57. |      * In supervisor mode when bit 15 of SysBase->AttnResched is set
  58. |        (dispatch pending bit).
  59. |        This ends by calling Dispatch() before falling down to user context.
  60. |      * In exec code. This ends by calling Switch() before going back to
  61. |        user code.
  62. |    * The task in SysBase->ThisTask is one of the ready tasks with the
  63. |      highest priority (round robin). There's an exception from this rule,
  64. |      too:
  65. |      * If dispatching is disabled and bit 7 of SysBase->AttnResched is set
  66. |        (switch pending bit) it is allowed to have a running task with a
  67. |        lower priority as a waiting one. This ends by calling Switch() as
  68. |        soon as the dispatcher is reactivated.
  69. |    * The ready list is sorted by priority.
  70. |
  71. |   HISTORY
  72. |
  73. |******************************************************************************
  74.     .globl    _Dispatch_68000
  75. _Dispatch_68000:
  76.     movel    a5,sp@-
  77.     movel    usp,a5
  78.     movel    sp@+,a5@-
  79.     movew    sp@+,a5@-
  80.     movel    sp@+,a5@-
  81.     moveml    d0-d7/a0-a4/a6,a5@-
  82. |     movel     4,a6
  83.     movew    #0x2700,sr            | disable interrupts
  84.     movel    a6@(0x114:W),a2             | SysBase->ThisTask
  85.     movel    a5,a2@(0x36)                | ThisTask->tc_SPReg
  86.     btst    #6,a2@(0xe)                 | TB_SWITCH
  87.     jeq    noswch
  88.     movel    a2@(0x82),a5
  89.     jsr    a5@
  90. noswch: moveb    a6@(0x126),a2@(0x10)        | store SysBase->IDNestCnt
  91.     moveb    #-1,a6@(0x126)              | set interrupt control
  92.     movew    #0xc000,0xdff09a
  93.     leal    a6@(0x196:W),a0             | &SysBase->TaskReady
  94. loop:    movel    a0@,a2                | ->lh_Head
  95.     movel    a2@,d0                | ->ln_Succ()
  96.     jeq    ready
  97.     stop    #0x2000             | wait for interrupts
  98.     movew    #0x2700,sr            | disable interrupts
  99.     jra    loop
  100. ready:    movel    d0,a1                | remove first node
  101.     movel    a1,a0@
  102.     movel    a0,a1@(4:W)
  103.     movel    a2,a6@(0x114:W)             | store it into SysBase->ThisTask
  104.     moveb    a2@(0x10),a6@(0x126)        | restore SysBase->IDNestCnt
  105.     jpl    nodis
  106.     movew    #0x4000,0xdff09a        | set interrupt control
  107. nodis:    btst    #7,a2@(0xe)                 | TB_LAUNCH
  108.     jeq    nolnch
  109.     movel    a2@(0x86),a5
  110.     jsr    a5@
  111. nolnch: movel    a2@(0x36),a5                | get ThisTask->tc_SPReg
  112.     btst    #5,a2@(0xe)                 | TF_EXCEPT set?
  113.     jeq    noexc
  114.     bclr    #5,a2@(0xe)
  115.     movel    a5@(14*4),d0                | swap returnaddress
  116.     movel    a5@(14*4+6),a5@(14*4)       | and stored a5
  117.     movel    d0,a5@(14*4+6)
  118.     movew    #0x4000,0xdff09a        | mini-disable
  119.     movel    a5,usp                | prepare going to user mode
  120.     movel    exloop,sp@-
  121.     clrw    sp@-
  122.     rte
  123. exloop: movel    a2@(0x1e),d0                | get signals causing the exception
  124.     andl    a2@(0x1a),d0
  125.     jeq    excend                | none?
  126.     eorl    d0,a2@(0x1e)                | disable them
  127.     movel    a2@(0x26),a1                | tc_ExceptData
  128.     movel    a2@(0x2a),a0                | tc_ExceptCode
  129.     movew    #0xc000,0xdff09a        | mini-enable
  130.     jsr    a0@
  131.     movew    #0x4000,0xdff09a
  132.     orl    d0,a2@(0x1e)                | reenable signals
  133.     jra    exloop                | look again
  134. excend: movew    #0xc000,0xdff09a        | OK, we're done.
  135.     moveml    sp@+,d0-d7/a0-a4/a6
  136.     movel    sp@+,a5
  137.     movew    sp@+,ccr
  138.     rts
  139. noexc:    movew    #0x2000,sr            | enable interrupts
  140.     moveml    a5@+,d0-d7/a0-a4/a6
  141.     movel    a5@+,sp@-
  142.     movew    a5@+,sp@-
  143.     movel    a5@+,sp@-
  144.     movel    a5,usp
  145.     movel    sp@+,a5
  146.     rte
  147.