home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / ctask.zip / TSKASM.ASM < prev    next >
Assembly Source File  |  1988-03-01  |  7KB  |  389 lines

  1. ;
  2. ;    CTask - Scheduler and miscellaneous utilities
  3. ;
  4. ;    Public Domain Software written by
  5. ;        Thomas Wagner
  6. ;        Patschkauer Weg 31
  7. ;        D-1000 Berlin 33
  8. ;        West Germany
  9. ;
  10.  IFDEF at
  11. .186
  12.  ENDIF
  13.     name    tskasm
  14.     .model    large
  15. ;
  16.     public    scheduler
  17.     public    _schedule
  18.     public    _c_schedule
  19.     public    _sched_int
  20. ;
  21.     public    _tsk_dis_int
  22.     public    _tsk_ena_int
  23.     public    _tsk_cli
  24.     public    _tsk_sti
  25.     public    _tsk_dseg
  26.     public    _tsk_flags
  27.     public    _tsk_outp
  28.     public    _tsk_inp
  29.     public    _tsk_nop
  30. ;
  31. ;
  32.     include    tsk.mac
  33. ;
  34. INT_FLAG    =    2h    ; Int enable flag in upper byte of flag reg
  35. r_flags        =    24    ; Offset of flag register on task stack
  36. ;
  37.     .data?
  38. ;
  39.     extrn    _tsk_current: dword
  40.     extrn    _tsk_eligible: dword
  41.     extrn    _tsk_preempt: byte
  42.     extrn    _idle_tcb: word
  43.     extrn    _tsk_pretick: byte
  44.     extrn    _tsk_var_prior: byte
  45. ;
  46.     .code
  47. ;                   
  48. _dgroup        dw    seg dgroup
  49. ;
  50. ;------------------------------------------------------------------------
  51. ;
  52. ;    enq    Enqueue tcb in queue. For local use only.
  53. ;        entry:    es:di = tcb to enqueue
  54. ;        exit:    -
  55. ;        uses:    ax, cx, dx, bp, di
  56. ;
  57. enq    proc    near
  58. ;
  59.     lds    bx,es:queue[di]        ; queue head pointer
  60.     mov    ax,ds
  61.     or    ax,bx    
  62.     jz    enq_end            ; nothing left to do if queue null
  63.     mov    dx,es:prior[di]        ; load priority of task
  64.     mov    word ptr es:queue[di],bx    ; init queue head pointer
  65.     mov    word ptr es:queue+2[di],ds
  66. enq_l:
  67.     mov    cx,bx            ; save last ptr
  68.     mov    bp,ds
  69.     lds    bx,next[bx]        ; load next
  70.     mov    ax,ds
  71.     or    ax,bx            ; end of chain?
  72.     jz    enq_found        ; then insert
  73.     cmp    dx,prior[bx]        ; compare priority
  74.     jbe    enq_l            ; loop if tasks prior less or equal
  75. ;
  76. enq_found:
  77.     mov    word ptr es:next[di],bx        ; set tasks next pointer
  78.     mov    word ptr es:next+2[di],ds
  79.     mov    bx,cx                ; last pointer
  80.     mov    ds,bp
  81.     mov    word ptr next[bx],di        ; last->next = task
  82.     mov    word ptr next+2[bx],es
  83. enq_end:
  84.     ret
  85. ;
  86. enq    endp
  87. ;
  88. ;
  89. ;    upd_prior: Update priority of tasks in eligible queue.
  90. ;               Only activated if tsk_var_prior is nonzero.
  91. ;
  92. upd_prior    proc    near
  93. ;
  94.     cmp    _tsk_var_prior,0
  95.     je    updp_end
  96. ;
  97.     les    di,_tsk_eligible
  98. pinc_loop:
  99.     mov    ax,es
  100.     or    ax,di            ; end of chain?
  101.     jz    updp_end
  102.     inc    es:prior[di]
  103.     jnz    pinc_nxt
  104.     dec    es:prior[di]
  105. pinc_nxt:
  106.     les    di,es:next[di]
  107.     jmp    pinc_loop
  108. ;
  109. updp_end:
  110.     ret
  111. ;
  112. upd_prior    endp
  113. ;
  114. ;
  115. ;    The scheduler. Note tat this routine is entered with the stack
  116. ;    set up as for an interrupt handler.
  117. ;
  118. scheduler    proc    far
  119. ;
  120.     cli
  121.  IFNDEF at
  122.     push    ax
  123.     push    cx
  124.     push    dx
  125.     push    bx
  126.     push    sp
  127.     push    bp
  128.     push    si
  129.     push    di
  130.  ELSE
  131.     pusha
  132.  ENDIF
  133.     push    ds
  134.     push    es
  135. ;
  136.     mov    ds,_dgroup        ; establish addressing of our vars
  137. ;
  138.     call    upd_prior        ; update priority
  139. ;
  140.     les    di,_tsk_current        ; get current tcb
  141.     mov    word ptr es:stack[di],sp ; store stack pointer & seg
  142.     mov    word ptr es:stack+2[di],ss
  143. ;
  144.     mov    _tsk_pretick,0        ; No preemption tick
  145.     and    _tsk_preempt,1        ; Turn off temp preempt flag
  146. ;
  147.     call    enq            ; Enqueue current task
  148. ;
  149.     mov    ds,_dgroup
  150.     les    di,_tsk_eligible
  151. ;
  152. ;    If eligible queue empty, activate idle task.
  153. ;
  154.     mov    ax,es
  155.     or    ax,di            ; is the eligible queue empty?
  156.     jnz    not_empty        ; jump if not
  157.     mov    di,offset _idle_tcb    ; else use idle tcb
  158.     mov    es,_dgroup
  159.     jmp    short sched_go
  160. ;
  161. ;    Eligible queue not empty, activate first eligible task.
  162. ;
  163. not_empty:
  164.     mov    ax,word ptr es:next[di]        ; load next pointer
  165.     mov    word ptr _tsk_eligible,ax    ; remove from queue
  166.     mov    ax,word ptr es:next+2[di]
  167.     mov    word ptr _tsk_eligible+2,ax
  168. ;
  169. sched_go:
  170.     mov    word ptr _tsk_current,di     ; set tcb into current
  171.     mov    word ptr _tsk_current+2,es
  172.     mov    ax,es:iniprior[di]        ; reset current tasks priority
  173.     mov    es:prior[di],ax
  174. ;
  175.     lds    si,es:stack[di]         ; load stack
  176.     or    byte ptr r_flags+1[si],INT_FLAG    ; enable interrupts
  177.     mov    es:state[di],ST_RUNNING        ; set task state
  178.     mov    cx,ds            ; switch stack
  179.     mov    ss,cx
  180.     mov    sp,si
  181.     pop    es            ; restore all registers
  182.     pop    ds
  183.  IFNDEF at
  184.     pop    di
  185.     pop    si
  186.     pop    bp
  187.     pop    bx            ; don't pop SP
  188.     pop    bx
  189.     pop    dx
  190.     pop    cx
  191.     pop    ax
  192.  ELSE
  193.     popa
  194.  ENDIF
  195.     iret
  196. ;
  197. scheduler    endp
  198. ;
  199. ;
  200. ;--------------------------------------------------------------------------
  201. ;
  202. ;
  203. ;    _sched_int  
  204. ;
  205. ;    Is the scheduler entry for interrupt handlers.
  206. ;    It checks if preemption is allowed, returning if not.
  207. ;    The stack is assumed to be set up as on interrupt entry.
  208. ;    
  209. _sched_int    proc    far
  210. ;
  211.     push    ds
  212.     push    bx
  213.     mov    ds,_dgroup
  214.     cmp    _tsk_preempt,0        ; preempt flags 0?
  215.     jne    no_sched        ; no scheduling if set
  216.     lds    bx,_tsk_current        ; current running task
  217.     test    flags[bx],F_CRIT    ; preemption allowed for this task?
  218.     jnz    no_sched        ; no scheduling if flag set
  219.     pop    bx            ; else go schedule
  220.     pop    ds
  221.     jmp    scheduler
  222. ;
  223. no_sched:
  224.     mov    ds,_dgroup
  225.     mov    _tsk_pretick,1        ; Mark preemption pending
  226.     pop    bx
  227.     pop    ds
  228.     iret
  229. ;
  230. _sched_int    endp
  231. ;
  232. ;
  233. ;    void far schedule (void)
  234. ;
  235. ;    Entry for calling the scheduler. Rearranges the stack to
  236. ;    contain flags.
  237. ;    NOTE: Uses ax,bx.
  238. ;
  239. _schedule    proc    far
  240. ;
  241.     pop    ax
  242.     pop    bx
  243.     pushf
  244.     push    bx
  245.     push    ax
  246.     cli
  247.     jmp    scheduler
  248. ;
  249. _schedule    endp
  250. ;
  251. ;
  252. ;    void far c_schedule (void)
  253. ;
  254. ;    Entry for conditionally calling the scheduler. Rearranges 
  255. ;    the stack to contain flags, then jumps to _sched_int.
  256. ;    NOTE: Uses ax,bx.
  257. ;
  258. _c_schedule    proc    far
  259. ;
  260.     pop    ax
  261.     pop    bx
  262.     pushf
  263.     push    bx
  264.     push    ax
  265.     cli
  266.     jmp    _sched_int
  267. ;
  268. _c_schedule    endp
  269. ;
  270. ;--------------------------------------------------------------------------
  271. ;
  272. ;    word tsk_dseg (void)
  273. ;
  274. ;    Returns current contents of DS register.
  275. ;
  276. _tsk_dseg    proc      far
  277.     mov    ax,ds
  278.     ret
  279. _tsk_dseg    endp
  280. ;
  281. ;
  282. ;    word tsk_flags (void)
  283. ;
  284. ;    Returns current contents of Flag register.
  285. ;
  286. _tsk_flags    proc    far
  287.     pushf
  288.     pop    ax
  289.     ret
  290. _tsk_flags    endp
  291. ;
  292. ;
  293. ;    int tsk_dis_int (void)
  294. ;
  295. ;    Returns current state of the interrupt flag (1 if ints were 
  296. ;    enabled), then disables interrupts.
  297. ;
  298. _tsk_dis_int    proc    far
  299. ;
  300.     pushf
  301.     pop    ax
  302.     mov    cl,9
  303.     shr    ax,cl
  304.     and    ax,1
  305.     cli
  306.     ret
  307. ;
  308. _tsk_dis_int    endp
  309. ;
  310. ;
  311. ;    void far tsk_ena_int (int state)
  312. ;
  313. ;    Enables interrupts if 'state' is nonzero.
  314. ;
  315. _tsk_ena_int    proc    far
  316. ;
  317.     push    bp
  318.     mov    bp,sp
  319.     mov    ax,6[bp]
  320.     pop    bp
  321.     or    ax,ax
  322.     jz    teiend
  323.     sti
  324. teiend:
  325.     ret
  326. ;
  327. _tsk_ena_int    endp
  328. ;
  329. ;
  330. ;    tsk_cli/tsk_sti: disable/enable int
  331. ;
  332. _tsk_cli    proc    far
  333.     cli
  334.     ret
  335. _tsk_cli    endp
  336. ;
  337. ;
  338. _tsk_sti    proc    far
  339.     sti
  340.     ret
  341. _tsk_sti    endp
  342. ;
  343. ;
  344. ;    tsk_inp/tsk_outp: input/output from/to port
  345. ;
  346. _tsk_inp    proc    far
  347. ;
  348.     push    bp
  349.     mov    bp,sp
  350.     mov    dx,6[bp]
  351.     in    al,dx
  352.     xor    ah,ah
  353.     pop    bp
  354.     ret
  355. ;
  356. _tsk_inp    endp
  357. ;
  358. ;
  359. _tsk_outp    proc    far
  360. ;
  361.     push    bp
  362.     mov    bp,sp
  363.     mov    dx,6[bp]
  364.     mov    al,8[bp]
  365.     out    dx,al
  366.     pop    bp
  367.     ret
  368. ;
  369. _tsk_outp    endp
  370. ;
  371. ;
  372. ;    void tsk_nop (void)
  373. ;
  374. ;    Do nothing. Used for very short delays.
  375. ;
  376. _tsk_nop    proc    far
  377. ;
  378.     jmp    short tnop1
  379. tnop1:
  380.     jmp    short tnop2
  381. tnop2:
  382.     ret
  383. ;
  384. _tsk_nop    endp
  385. ;
  386.     end
  387.  
  388.  
  389.